Caching 帮助我理解用于延迟加载的EntityFramework4缓存

Caching 帮助我理解用于延迟加载的EntityFramework4缓存,caching,entity-framework-4,Caching,Entity Framework 4,我在EntityFramework4.0中遇到了一些意想不到的行为,我希望有人能帮助我理解这一点。我使用northwind数据库来回答这个问题。我还使用默认代码生成器,而不是poco或自跟踪。我希望在任何时候查询框架的上下文时,如果还没有获取这些对象,就只能进行一次往返。如果我关闭延迟加载,我确实会有这种行为。目前在我的应用程序中,我很快地打开了延迟加载,然后又关闭了它,这样我就可以获得所需的行为。那太糟糕了,所以请帮忙。下面是一个很好的代码示例,可以演示我的问题 Public Sub Many

我在EntityFramework4.0中遇到了一些意想不到的行为,我希望有人能帮助我理解这一点。我使用northwind数据库来回答这个问题。我还使用默认代码生成器,而不是poco或自跟踪。我希望在任何时候查询框架的上下文时,如果还没有获取这些对象,就只能进行一次往返。如果我关闭延迟加载,我确实会有这种行为。目前在我的应用程序中,我很快地打开了延迟加载,然后又关闭了它,这样我就可以获得所需的行为。那太糟糕了,所以请帮忙。下面是一个很好的代码示例,可以演示我的问题

Public Sub ManyRoundTrips()
    context.ContextOptions.LazyLoadingEnabled = True
    Dim employees As List(Of Employee) = context.Employees.Execute(System.Data.Objects.MergeOption.AppendOnly).ToList()

    'makes unnessesary round trip to the database, I just loaded the employees'
    MessageBox.Show(context.Employees.Where(Function(x) x.EmployeeID < 10).ToList().Count)
    context.Orders.Execute(System.Data.Objects.MergeOption.AppendOnly)
    For Each emp As Employee In employees
        'makes unnessesary trip to database every time despite orders being pre loaded.'
        Dim i As Integer = emp.Orders.Count
    Next
End Sub

Public Sub OneRoundTrip()
    context.ContextOptions.LazyLoadingEnabled = True
    Dim employees As List(Of Employee) = context.Employees.Include("Orders").Execute(System.Data.Objects.MergeOption.AppendOnly).ToList()

    MessageBox.Show(employees.Where(Function(x) x.EmployeeID < 10).ToList().Count)

    For Each emp As Employee In employees
        Dim i As Integer = emp.Orders.Count
    Next
End Sub

为什么第一个代码块会产生不必要的往返?

您的期望是不正确的。查询总是查询数据库。总是这是因为LINQ总是转换为SQL


要从上下文(如果已经获取)加载对象,并从数据库(如果尚未获取)加载对象,请使用。

第一次“不必要”的行程是必要的-您执行了一个新的查询,同时数据库可能已更改。如果在存储查询结果的位置使用employees变量,则无需访问数据库

第二个是必需的,因为您要求它为每个员工获取订单。使用延迟加载和不包含,直到您使用emp.Orders.Count请求它读取订单,它才会读取订单

请记住,在开始对查询进行迭代或调用要求它将LINQ迭代到EF的某个方法之前,不会执行任何操作。如果您将该查询保存在一个变量中,然后调用。依靠它,将有一个往返过程。如果您使用相同的查询并开始枚举它,那么将有另一个往返。如果该查询中的实体本身具有关系,并且每次访问一个实体时都会延迟加载,那么还会有另一个往返


您的第二个示例显示了如何正确执行此操作,如果您提前知道您需要订单,这就是急切加载。请注意,您没有返回上下文为员工再次询问,而是重用了已加载的文件。

Ok在第二段描述的场景中使用了一些设置。我还是很困惑。如果我关闭延迟加载,它将提供我想要的结果,而无需再次往返数据库。如果我打开惰性加载,它将进行往返。有时我不能把我需要的所有东西都放在include中,或者查询的性能很差,因为它太大了。那么,当我关闭延迟加载时,为什么会出现这两种行为呢?