使用AsNoTracking()的实体框架延迟加载

约翰

目前,我们正在对Entity Framework使用延迟加载并运行到out of memory exception之所以会遇到此异常,是因为Linq查询会加载大量数据,而在后期则使用延迟加载来加载导航属性。但是,因为我们不使用NoTrackingChangesEntity Framework,所以缓存会很快建立,这会导致内存不足错误。

我对EF的理解是,NoTrackingChanges除非您要更新查询中返回的对象,否则我们应该始终在查询中使用

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

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

但出现以下错误:

System.InvalidOperationException:当使用NoTracking合并选项返回对象时,仅当EntityCollection或EntityReference不包含对象时才可以调用Load。

埃里克·飞利浦

您已指定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

我真的不相信使用AsNoTracking会阻止使用延迟加载

可以很快地对其进行测试:

DotNetFiddle完整示例

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);
    }
}

输出:

==========开始添加:movie1
=======================结束添加:movie1 =========== ====
Vin Diesel
Vin Diesel
运行时异常(第31行):对象引用未设置为对象的实例。

该变量m1由上下文跟踪,因此可以延迟加载导航属性并打印该值。m2不会被跟踪,但是我明确包含了navigation属性,因此它会打印值。m3不会被跟踪,并且我也没有明确地包含它,因此该值为null,我们得到了NRE。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章