4

我是实体框架的新手。

我有一个担心:

我需要遍历通过 LINQ to Entities 收集的大量数据,这些数据以匿名类型组合了来自不同实体的几个属性。

如果我需要一个一个地读取这个查询的返回项直到最后,我是否有 OutOfMemory 异常的风险,因为集合是 BIG 或 EF 隐式使用 SqlDataReader?

(或者我应该使用 EntityDateReader 来确保我按顺序读取 Db(但是我必须将我的查询生成为我猜的字符串))

4

2 回答 2

4

正如我所看到的,您可以做两件事,首先使用 .AsNoTracking 关闭跟踪,这在大多数情况下会将您的内存集减少一半,这可能就足够了。

如果您的集合仍然太大,请使用跳过并以块的形式拉下结果集。您还应该将其与 AsNoTracking 结合使用,以确保跟踪不消耗内存

编辑:

例如,您可以使用类似于以下内容的内容来循环遍历 1000 个块中的所有项目。下面的代码一次只能在内存中保存 1000 个项目。

int numberOfItems = ctx.MySet.Count();

for(int i = 0; i < numberOfItems + 1000; i+=1000)
{
    foreach(var item in ctx.MySet.AsNoTracking().Skip(i).Take(1000).AsEnumerable())
    {
         //do stuff with your entity
    }
}
于 2012-10-12T07:24:06.773 回答
0

如果数据量像你说的那么大,我建议你不要在这种情况下使用 EF。EF 很棒,但有时您需要回退并使用标准 SQL 以获得更好的性能。

看看 Dapper.NET https://github.com/SamSaffron/dapper-dot-net

如果您真的想在每种情况下都使用 EF,我建议您使用有界上下文(多个 DBContext)。

在多个较小的上下文中拆分模型将提高性能,因为当 EF 创建上下文的内存模型时,您将使用更少的资源。

上下文越大,用于生成和维护该内存模型的资源就越多。

您还可以在共享多个上下文的实例时分离附加,这样您仍然不会加载所有模型。

于 2012-10-12T07:34:50.667 回答