Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架性能-每个关系属性调用缓慢_C#_Sql_Entity Framework - Fatal编程技术网

C# 实体框架性能-每个关系属性调用缓慢

C# 实体框架性能-每个关系属性调用缓慢,c#,sql,entity-framework,C#,Sql,Entity Framework,我有一个大型数据库,它有一个包含几十万条记录的主表,然后有30-40个不同的关系表从中连接以获取额外的数据 我创建了一个到这个数据库的EF连接,我能够毫无问题地提取数据 我们项目的目标是将200K对象保存在内存中,保存在我们自己的定制POCO类中,这些类与我们现有的数据库结构不匹配。这里的想法是,对于缓存在内存中的20万个项目,当有人去获取其中的8000个项目时,它应该返回得非常快 我也能够通过MemoryCache实现这一点 问题在于POCO clas对象的原始加载。当我遍历我的记录列表并填充

我有一个大型数据库,它有一个包含几十万条记录的主表,然后有30-40个不同的关系表从中连接以获取额外的数据

我创建了一个到这个数据库的EF连接,我能够毫无问题地提取数据

我们项目的目标是将200K对象保存在内存中,保存在我们自己的定制POCO类中,这些类与我们现有的数据库结构不匹配。这里的想法是,对于缓存在内存中的20万个项目,当有人去获取其中的8000个项目时,它应该返回得非常快

我也能够通过MemoryCache实现这一点

问题在于POCO clas对象的原始加载。当我遍历我的记录列表并填充我的POCO对象时,这似乎比我希望的要花更多的时间。我相信EF正在对每个记录进行SQL调用,以获取关系数据。所以当我说:

foreach(var o in MyEntities.Stuff)
{
var x = new MyCustomClass();
x.Property1 = o.RelationalTableA.PropertyX;
x.Property2 = o.RelationalTableB.PropertyY;
x.Property3 = o.RelationalTableC.PropertyZ;
MyPocoList.Add(o);
}
这似乎需要几百毫秒

那么,对于10万个项目,可能是300毫秒*100000=8小时

仅将poco对象设置为硬编码值(对于100K项)就需要几分钟,这是在内存中加载大量记录的合理时间

是否有优化方法可用于EF,使其不会对我设置的每个属性运行联接查询

编辑以添加:

在我的代码中,我还根据返回记录中的值创建不同类型的类。例如:

IInterface x;
if(o.PropertyA == "A")
{
  x = new MyCustomClass1();
}
else if(o.PropertyA == "B")
{
  x = new MyCustomClass2();
}

.

手动连接到其他表可能会更好:

var MyPocoList = 
    from x in MyEntities.Stuff
    join a in RelationalTableA on x.id == a.id
    join b in RelationalTableB on x.id == b.id
    select new MyCustomClass(X = a.PropertyX, Y = b.PropertyY);

您应该做两件事或使用@BG100的替代方案:

用于在加载数据时加载相关实体

如果在执行foreach循环的枚举器之前,您预先知道要加载数据的数据量,请使用.ToList。如果不使用.ToList,则在执行查询时加载数据,该查询与使用SqlDataReader时相同


SQL Server Profiler说正在对服务器执行哪些查询?您是否有足够的索引和其他数据库优化?请尝试MyEntities.Stuff.ToList中的foreachvar o如果您想要性能,请不要使用EF。编写存储过程并使用数据读取器。你的物体有多大?您的硬编码结果似乎很慢。您是否正在访问交换文件或其他内容?如果使用sql事件探查器,您应该能够看到实际运行的sql。此外,我还要补充一点,我认为您的缓存想法可能有点偏离目标。SQLServer非常擅长快速返回结果,并且可以自己进行缓存。因此,创建自己的“内存数据库”的价值有限。缓存的真正价值在于为已知结果从数据库的共享资源中移除负载。谢谢,这很有帮助。我将尝试一下,看看它的性能如何。这显著提高了性能,从某种意义上说,这与我准备放弃EF并使用大型存储过程将所有数据恢复到原来的状态是一样的。。。。现在加载10000个项目大约需要12秒。这也许可以进一步调整,但至少现在是合理的。
foreach(var o in MyEntities.Stuff
        .Include(x => x.RelationalTableA)
        .Include(x => x.RelationalTableB)
        .Include(x => x.RelationalTableC)
        .ToList())
{
    var x = new MyCustomClass();
    x.Property1 = o.RelationalTableA.PropertyX;
    x.Property2 = o.RelationalTableB.PropertyY;
    x.Property3 = o.RelationalTableC.PropertyZ;
    MyPocoList.Add(o);
}