c# - 使用 include 不会改变行为

标签 c# sql-server performance entity-framework entity-framework-6

有人可以帮我澄清一下之间的区别:

 var query = awlt.People.Include(p => p.EmailAddresses)
                    .Where(p => p.LastName.Equals(lastName))
                    .SelectMany(a => a.EmailAddresses)
                    .Select(a => a.EmailAddress1); 

 var query = awlt.People
                    .Where(p => p.LastName.Equals(lastName))
                    .SelectMany(a => a.EmailAddresses)
                    .Select(a => a.EmailAddress1);

我在两种情况下都得到相同的结果,但不知道其中的区别。 Eager Loading 是否需要使用 Include

最佳答案

这两个查询都是通过使用 Eager Loading 检索相关数据(是的,Eager loading 是通过使用 Include 方法实现的,如您所料)和使用默认情况下的 Lazy loading 进行第二次查询。但是由于 Select()SelectMany() 操作 Include(),您的查询将只返回 EmailAddresses 方法不会改变行为。要查看何时 Include() 方法在您的示例中很重要,请阅读以下几行,我将在一个示例中证明它:

要了解这两种加载相关实体之间的一些区别 预加载 通常在您需要主表的所有检索行的相关数据时更有效。而且当关系 不是太多时,eager loading 将是减少服务器上进一步查询的好习惯。但是当你知道你不会立即需要一个属性时,延迟加载可能是一个不错的选择。在您的数据库上下文将被处理并且延迟加载不再发生的情况下,预加载也是一个不错的选择。 为了证明一种是延迟加载,一种是急切加载,请考虑以下代码:

public List<Person> GetEmailAddresses()
{
    using (yourEntities awlt = new yourEntities())
    {
        var query = awlt.People
                .Where(p => p.LastName.Equals(lastName));
        return query.ToList();
    }
}

调用此方法后,您将无法延迟加载相关实体,因为数据库已被释放。证明试试这个:

var query = GetEmailAddresses();
foreach (var item in query.SelectMany(a => a.EmailAddresses).Select(a => a.EmailAddress1))
{
    MessageBox.Show(item);                
}

你会得到这个错误:

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

但是,如果您将 GetEmailAddresses 更改为使用 Eager Loading,如下所示:

public List<Person> GetEmailAddresses()
{
    using (yourEntities awlt = new yourEntities())
    {
        var query = awlt.People.Include("EmailAddresses")
                .Where(p => p.LastName.Equals(lastName));
        return query.ToList();
    }
}

那么下面的代码应该可以正常工作:

var query = GetEmailAddresses();
foreach (var item in query.SelectMany(a => a.EmailAddresses).Select(a => a.EmailAddress1))
{
    MessageBox.Show(item);                
}

因此,在您的数据库上下文将被释放的情况下,Eager Loading 将是更好的选择。

关于c# - 使用 include 不会改变行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36961249/

相关文章:

sql - 查找 IP 地址 block 表中的间隙

php - 从 2 个表中选择时,Mysql 查询非常慢

java - 修改编辑距离算法以不计算所有距离

c# - 如何提供要在函数中使用的字段?

c# - 将 XAML 中的标签文本设置为字符串常量

c# - 安装自研Windows Service

c# - 使用 linq 对行求和

.net - SQL Server 中的异步处理与 .NET 异步处理

sql - 如何在多数据库环境中使用 Dapper?

python 两个大型二维列表之间的快速均方误差