C# C实体框架-当您用子查询填充列表时,数据库中会发生什么?
我使用带有MS SQL Server后端的实体框架填写了一些模型。该模型由一个记录和多个与该记录关联的记录组成。我使用一个列表来保存这些记录。在LINQ实体框架查询中,我编写了一个子查询来获取列表,但我不知道当时是否正在访问数据库。我可能想在以后添加where子句等 这就是我目前的做法:C# C实体框架-当您用子查询填充列表时,数据库中会发生什么?,c#,database,entity-framework,list,linq,C#,Database,Entity Framework,List,Linq,我使用带有MS SQL Server后端的实体框架填写了一些模型。该模型由一个记录和多个与该记录关联的记录组成。我使用一个列表来保存这些记录。在LINQ实体框架查询中,我编写了一个子查询来获取列表,但我不知道当时是否正在访问数据库。我可能想在以后添加where子句等 这就是我目前的做法: public class TestOwner { public Owner OwnerRecord { get; set; } public List<OwnerUser> Owne
public class TestOwner
{
public Owner OwnerRecord { get; set; }
public List<OwnerUser> OwnerUsers { get; set; }
public TestOwner()
{
}
}
public static class DataTools
{
public static TestOwner testQuery()
{
//Create the holder variable for the database context.
MyEntities db = (MyEntities)CommonDataTools.GetDbContext();
//Places the database context in a using statement to have it disposed of when we are done.
using (db)
{
//Get the test owner.
return (from o in db.Owner
where o.owner_id == 44
select new TestOwner()
{
OwnerRecord = o,
OwnerUsers = (from ou in db.OwnerUser
where ou.owner_id == o.owner_id
select ou).ToList() //This is the part in question, what does this do in the database? Is this the proper way?
}).FirstOrDefault();
}
}
}
注意我将子查询转换为列表的查询
我一直在想这是否更好:
public class TestOwner
{
public Owner OwnerRecord { get; set; }
public IEnumerable<OwnerUser> OwnerUsers { get; set; }
public TestOwner()
{
}
}
通过使用IEnumerable,我不需要.ToList,但我不确定这是否会在以后伤害我
那么对于列表版本,它在数据库中起什么作用呢?查询是否部分运行?这是处理这种情况的正确方法吗?如果没有,那么如何正确地填充从数据库填充的对象内部的列表?首先,您应该运行,并使用当前代码查看生成了多少查询并发送到数据库
实体框架根据LINQ语句生成sql查询。这些查询将被发送到数据库。现在让我们考虑一下当前的代码:
第一部分:
return (from o in db.Owner
where o.owner_id == 44
这将返回一个IQueryable对象,当在循环中枚举时,该对象生成并触发DB中的查询,或者调用“count、sum”等聚合函数或.ToList等转换函数
同样的事情也会发生在你内心的LINQ语句上。但区别在于,每次枚举外部语句结果时,子查询都会被触发到数据库,因为您有一个.ToList。
第二部分:
(from ou in db.OwnerUser
where ou.owner_id == o.owner_id
select ou).ToList()
如果删除“ToList”怎么办?sql将生成为包含子查询的单个语句。所以枚举只会在数据库中触发查询一次。因此,这将减少您往返DB的次数
此外,IEnumerable是一个更好的选择,因为它支持像IQueryable一样的延迟执行
进一步阅读如果您使用的是EF6或更高版本,那么可以使用这一方法来了解实际情况。这将记录LINQ查询生成的SQL。真让人大开眼界。有趣。所以使用ToList似乎不是我想要的,因为它会运行太多的查询。为了进一步阅读,我阅读了您的链接,发现IQueryable比IEnumerable更好,因为您可以将其添加到其中,并将其合并到一个SQL语句中。我在这里怎么处理?如果我将模型更改为对列表部分使用IQueryable,那么在运行FirstOrDefault行时会执行它吗?我基本上想知道如何让它与正确的一个数据库调用一起工作。为了扩展,我只是尝试将IEnumerable行更改为IQueryable,一旦我从函数返回并且数据库上下文消失,我尝试使用IQueryable值和get:对于物化查询结果异常,不支持此方法。我这样做了,它也起了作用,但是在您的进一步阅读链接中,它指出如果我想在事实之后向IEnumerable添加where子句,它将执行查询,然后在内存中运行,而IQueryable只是一条添加了where的sql语句。我希望有一个在所有情况下都能工作的方法。这是真的,但您需要一个与IQueryable关联的DbContext,在您的情况下,它不适用于您的实体,因为您的实体没有与任何上下文对象关联。IQueryable生成在发生延迟执行时执行的查询。因此,除非生成枚举数,否则保留IEnumerable对象也会阻止执行。我提供的链接仅供参考,不是解释的附加内容。以防万一,如果你想知道IQueryable而不是IEnumerable。可能这个链接不是目前最好的资源。