Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C实体框架-当您用子查询填充列表时,数据库中会发生什么?_C#_Database_Entity Framework_List_Linq - Fatal编程技术网

C# C实体框架-当您用子查询填充列表时,数据库中会发生什么?

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

我使用带有MS SQL Server后端的实体框架填写了一些模型。该模型由一个记录和多个与该记录关联的记录组成。我使用一个列表来保存这些记录。在LINQ实体框架查询中,我编写了一个子查询来获取列表,但我不知道当时是否正在访问数据库。我可能想在以后添加where子句等

这就是我目前的做法:

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。可能这个链接不是目前最好的资源。