简体   繁体   English

在实体框架中处理大数据的最佳方式

[英]Best way to handle large data in entity framework

Hi I am using EF6 where I have large data to select from database where my query as follows:嗨,我正在使用 EF6,其中我有大量数据可以从我的查询的数据库中进行选择,如下所示:

var EntityInfo = _contextRegister.Entities.Where(x => x.IsDeleted != true).ToList();
foreach (var itm in EntityInfo)
{
    Entity.Entity entity = new Entity.Entity();
    entity.MainActivityId = itm.MainActivityId;
    entity.SubGroupId = itm.SubGroupId;
    entity.Id = Convert.ToInt32(itm.Id);
-------
    entity.UAECityRegion = _contextFRAMEWORK.UAECityRegions.Where(m => m.Id == itm.UAECityRegionId).Select(m => m.RegionName).FirstOrDefault();
    var voucherstautus = _contextRegister.EPayVoucherDatas.Where(m => m.EntityId == itm.Id).ToList();
    foreach (var item in voucherstautus)
    {
        if (item.VoucherStatus == 10)
        {
            entity.PaymentStatus = Convert.ToInt32(item.VoucherStatus);
            break;
        }
     }

     entityList.Add(entity);
}

This query taking more than 10mins where how can I make this query better or should I use stored procedure instead of framework?这个查询需要超过 10 分钟,我怎样才能使这个查询更好,或者我应该使用存储过程而不是框架?

As far as I can see there is a 1:1 relationship between Entities and EPayVoucherDatas (otherwise your code _contextRegister.EPayVoucherDatas.Where(m => m.EntityId == itm.Id) wouldn't work).据我EPayVoucherDatasEntitiesEPayVoucherDatas之间存在 1:1 的关系(否则您的代码_contextRegister.EPayVoucherDatas.Where(m => m.EntityId == itm.Id)将不起作用)。 So at first ensure you have modeled this relationship in your EF model .因此,首先确保您已在 EF 模型中对这种关系进行建模

If that is true you could write something like this:如果这是真的,你可以写这样的东西:

_contextRegister.EPayVoucherDatas.Where(m => !m.Entity.IsDeleted);

That already eliminates a part of your problems.这已经消除了您的部分问题。

Another part is your usage of another database _contextFRAMEWORK , which seems to contains some other data under the same Ids.另一部分是您对另一个数据库_contextFRAMEWORK ,它似乎包含相同 ID 下的一些其他数据。 In your current implementation you ask for a specific region for each item separately.在您当前的实现中,您分别要求每个项目的特定区域。 But depending on the size of this table it could be wiser to pull this whole table once (outside of the for-loop) and make the lookup locally.但是根据该表的大小,将整个表拉出一次(在 for 循环之外)并在本地进行查找可能更明智。 Also you have this if-statment that sets the PaymentStatus to 10 if the VoucherStatus is also 10. What is in all other cases`?如果 VoucherStatus 也是 10,你也有这个 if 语句将 PaymentStatus 设置为 10。在所有其他情况下是什么? Maybe you can always map the PaymentStatus from the VoucherStatus?也许您总是可以从 VoucherStatus 映射 PaymentStatus?

A lot of question and not a real answer, cause as usual it depends .很多问题而不是真正的答案,因为像往常一样,这取决于 Try to minimize the amount of calls to the database and check how many entities each call returns.尽量减少对数据库的调用量,并检查每次调用返回的实体数量。 Filter by some conditions as early as possible to minimize the amount of data that the server returns and try to make as few connections as possible to the server.尽早按某些条件进行过滤,以尽量减少服务器返回的数据量,并尽量减少与服务器的连接。 Even if that results in quite complex queries.即使这会导致相当复杂的查询。 This is not a problem for a SQL server normally, cause that's it for what it was made for.这对于 SQL 服务器来说通常不是问题,因为这就是它的用途。

1) Check if the DataBase Indexes are created for each field that is used in the WHERE conditions, for example: 1) 检查是否为 WHERE 条件中使用的每个字段创建了数据库索引,例如:

x.IsDeleted
m.Id 
m.EntityId

You can create indexes using the Model Builder:您可以使用模型构建器创建索引:

modelBuilder.Entity<Person>()
    .HasIndex(p => p.Name)
    .IsUnique();

See https://stackoverflow.com/a/47031294/194717https://stackoverflow.com/a/47031294/194717

You can also create indexes with IndexAttribute您还可以使用 IndexAttribute 创建索引

public class Blog
{
    public int Id { get; set; }
    public string Title { get; set; }

    [Index]
    public int Rating { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

See https://blog.oneunicorn.com/2014/02/15/ef-6-1-creating-indexes-with-indexattribute/https://blog.oneunicorn.com/2014/02/15/ef-6-1-creating-indexes-with-indexattribute/

2) You shouldn't hit the database two times for each Entities record. 2)您不应该为每个实体记录两次访问数据库。 Try to write it as a JOIN instead ( .Include() ).尝试将其写为 JOIN ( .Include() )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM