c# - Entity Framework 延迟加载 AsNoTracking()

标签 c# entity-framework entity-framework-6

我们目前正在为 Entity Framework 使用延迟加载并遇到内存不足异常。我们遇到此异常的原因是因为 Linq 查询加载了大量数据,并且在后期使用延迟加载来加载导航属性。但是因为我们不使用 NoTrackingChanges Entity Framework 缓存建立得非常快,导致内存不足错误。

我对 EF 的理解是我们应该始终在查询中使用 NoTrackingChanges 除非您想更新从查询返回的对象。

然后我使用 NoChangeTracking 进行了测试:

var account = _dbcontext.Account
                        .AsNoTracking()
                        .SingleOrDefault(m => m.id == 1); 
var contactName = account.Contact.Name

但我收到以下错误:

System.InvalidOperationException: When an object is returned with a NoTracking merge option, Load can only be called when the EntityCollection or EntityReference does not contain objects.

最佳答案

您已指定 EF 不跟踪实例化的 Account 值:

var account = _dbcontext.Account.AsNoTracking().SingleOrDefault(m=>m.id == 1);

因此尝试访问它们的导航属性将永远行不通:

var contactName = account.Contact.Name

您可以使用 Include() 显式包含所需的导航属性。所以以下应该有效:

var account = _dbcontext.Account
  .Include(a => a.Contact)
  .AsNoTracking()
  .SingleOrDefault(m=>m.id == 1);

var contactName = account.Contact.Name;  // no exception, it's already loaded

I'm really not convinced that using AsNoTracking prevents from using lazy loading

它可以很快被测试:

DotNetFiddle Full Example

public static void Main()
{
    var actor1 = new Actor { Id = 1, Name = "Vin Diesel" }; 
    var movie1 = new Movie { Id = 1, Title = "Fast and Furious", PrimaryActor = actor1 };
    using (var context = new MovieDb())
    {

        Console.WriteLine("========= Start Add: movie1 ==============");
        context.Movies.Add(movie1);
        context.SaveChanges();
        Console.WriteLine("========= END Add: movie1 ==============");

        var m1 = context.Movies.First();
        Console.WriteLine(m1.PrimaryActor.Name);

        var m2 = context.Movies.Include(m => m.PrimaryActor).AsNoTracking().First();
        Console.WriteLine(m2.PrimaryActor.Name);

        var m3 = context.Movies.AsNoTracking().First();
        Console.WriteLine(m3.PrimaryActor.Name);
    }
}

输出:

========= Start Add: movie1 ==============
========= END Add: movie1 ==============
Vin Diesel
Vin Diesel
Run-time exception (line 31): Object reference not set to an instance of an object.

变量 m1 由上下文跟踪,因此它可以延迟加载导航属性并打印值。 m2 未被跟踪,但我已明确包含导航属性,因此它会打印值。 m3 未被跟踪,我没有明确包含它,因此值为 null,我们得到一个 NRE。

关于c# - Entity Framework 延迟加载 AsNoTracking(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47188678/

相关文章:

c# - 如何序列化用 [ScriptIgnore] 属性装饰的属性?

c# - 将 SSL 应用程序从 Java 移植到 C#

sql - Entity Framework -属性IN子句用法

entity-framework - 检查是否有任何待保存的更改

powershell - 在没有 Visual Studio 的情况下, Entity Framework 模型优先还是数据库优先和代码优先?

c# - 在 C# 桌面应用程序中使用网页作为 UI?

c# - ASP.Net MVC 模型绑定(bind) - 如何更改日期格式?

linq - 无法将原始 SQL 查询映射到 DataRow

c# - .Net 如何使用上下文处理 LINQ-To-Entity 中的连接?

c# - EF 6 - 代码第一个无效的一对一外键关系