Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.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# 为什么将IQueryable转换为.toList()将数据包含到对象DbContext?_C#_Asp.net_Entity Framework_Asp.net Mvc 4_Extension Methods - Fatal编程技术网

C# 为什么将IQueryable转换为.toList()将数据包含到对象DbContext?

C# 为什么将IQueryable转换为.toList()将数据包含到对象DbContext?,c#,asp.net,entity-framework,asp.net-mvc-4,extension-methods,C#,Asp.net,Entity Framework,Asp.net Mvc 4,Extension Methods,我有一个使用entityframework的代码示例 这一个正在工作: public ActionResult Index() { BlogContext dbContext = new BlogContext(); dbContext.Posts.Include(a => a.Tags).ToList(); return View(dbContext.Posts.ToList()); } 而这不是: pub

我有一个使用entityframework的代码示例

这一个正在工作:

    public ActionResult Index()
    {
        BlogContext dbContext = new BlogContext();
        dbContext.Posts.Include(a => a.Tags).ToList();
        return View(dbContext.Posts.ToList());
    }
而这不是:

    public ActionResult Index()
    {
        BlogContext dbContext = new BlogContext();
        dbContext.Posts.Include(a => a.Tags);
        return View(dbContext.Posts.ToList());
    }
所以我不明白,为什么仅强制转换到
列表
就足以包含来自模型的标记(
列表
),我会理解它是否会是这样,这也很好(我正在使用它!问题不是关于代码格式化!):

但这并不需要。所以我的问题是: 为什么将IQueryable强制转换为toList会将数据包含到对象
dbContext
我知道在entityframework中,我们正在使用扩展,但据我所知,扩展返回的值并没有分配给对象

这是我正在崩溃的部分观点:

@using BlogWeb.Models
@model Post


    <h1>@Model.Title</h1>
    <p class="lead">
        by <a href="#">1234</a>
    </p>
    <hr>
    <p>@Model.Created</p>
    <p class="lead">
        @Model.Body
    </p>
    @Html.Partial("_Tags", Model.Tags) -<< this is what is throwing error
    <hr>
@使用BlogWeb.Models
@标杆
@模型名称

通过


@模型。创建

@模特。身体


@Html.Partial(“_Tags”,Model.Tags)-当您将那些Linq方法链接在一起时,您正在幕后构建一个查询。添加
Include(…)
告诉它在执行之前加入上的其他数据。调用
ToList()
时,将使用
Include(…)
执行Linq查询


在第二个示例中,您没有执行查询,因此当您调用
dbContext.Posts.ToList()
时,它没有缓存任何内容,并且是在没有
Include(…)

的情况下执行的另一个查询。当您将这些Linq方法链接在一起时,您正在幕后构建一个查询。添加
Include(…)
告诉它在执行之前加入上的其他数据。调用
ToList()
时,将使用
Include(…)
执行Linq查询


在第二个示例中,您没有执行查询,因此当您调用
dbContext.Posts.ToList()
时,它没有缓存任何内容,并且是一个不同的查询,在执行时没有
Include(…)

请记住,在使用集合
ToArray
aseEnumerable
(我想这就是全部)所有这些都强制EF对数据库执行,并将对象物化回内存。换句话说,如果您不迭代集合或调用其中一个集合,那么什么都不会发生

这一个正在工作:

    public ActionResult Index()
    {
        BlogContext dbContext = new BlogContext();
        dbContext.Posts.Include(a => a.Tags).ToList();
        return View(dbContext.Posts.ToList());
    }
EF在内部跟踪实体的状态。因此使用code
dbContext.Posts.Include(a=>a.Tags)。ToList();
将检索所有post以及每个post的标记。然后调用
返回视图(dbContext.Posts.ToList())
标签已经从数据库中检索到,除非你在那一瞬间添加了一篇新文章,否则不会有任何问题

而这不是:

    public ActionResult Index()
    {
        BlogContext dbContext = new BlogContext();
        dbContext.Posts.Include(a => a.Tags);
        return View(dbContext.Posts.ToList());
    }
dbContext.Posts.Include(a=>a.Tags);
告诉EF包含标记,但不使用它做任何其他事情,实际上您只是扔掉了正在使用的命令。然后调用
dbContext.Posts.ToList()
,它只检索帖子。因此,现在您有了帖子,但没有包含的标记

public ActionResult Index()
{
    BlogContext dbContext = new BlogContext();
    var model = dbContext.Posts.Include(a => a.Tags).ToList();
    return View(model);
}

这是使用EF的方法,因为现在您不会丢弃
DbSet
上的结果。所有EF扩展命令都具体化了某些内容,您应该使用该结果。
DbSet
本身并不是为了跟踪在其上执行的内容(有EF实体跟踪的例外,但这不是我要说的)。DbSet不是命令对象,所以不能这样使用它。

请记住,在使用集合时,
ToList
ToArray
可计算的
(我想这就是全部)all强制EF对数据库执行,并将对象物化回内存。换句话说,如果您不迭代集合或调用其中一个集合,则什么也不会发生

这一个正在工作:

    public ActionResult Index()
    {
        BlogContext dbContext = new BlogContext();
        dbContext.Posts.Include(a => a.Tags).ToList();
        return View(dbContext.Posts.ToList());
    }
EF在内部跟踪实体的状态。因此使用code
dbContext.Posts.Include(a=>a.Tags)。ToList();
将检索所有post以及每个post的标记。然后调用
返回视图(dbContext.Posts.ToList())
标签已经从数据库中检索到,除非你在那一瞬间添加了一篇新文章,否则不会有任何问题

而这不是:

    public ActionResult Index()
    {
        BlogContext dbContext = new BlogContext();
        dbContext.Posts.Include(a => a.Tags);
        return View(dbContext.Posts.ToList());
    }
dbContext.Posts.Include(a=>a.Tags);
告诉EF包含标记,但不使用它做任何其他事情,实际上您只是扔掉了正在使用的命令。然后调用
dbContext.Posts.ToList()
,它只检索帖子。因此,现在您有了帖子,但没有包含的标记

public ActionResult Index()
{
    BlogContext dbContext = new BlogContext();
    var model = dbContext.Posts.Include(a => a.Tags).ToList();
    return View(model);
}

这是使用EF的方法,因为现在您不会丢弃
DbSet
上的结果。所有EF扩展命令都具体化了某些内容,您应该使用该结果。
DbSet
本身并不是为了跟踪在其上执行的内容(使用EF entity tracking的exeption,但这不是我要说的)。DbSet不是命令对象,所以不能使用它。

当您调用
dbContext.Posts.Include(a=>a.Tags);
时,您只是在创建一个查询。没有从数据库中引入任何元素


调用
dbContext.Posts.Include(a=>a.Tags).ToList();
时,您正在创建查询并执行它。元素被加载到内存中(包括
Tags
属性)

在第二个示例中,当您执行
返回视图(dbContext.Posts.ToList());
时,内存中没有任何元素,并且当元素来自数据库时,您不会要求包含
标记


在第一个示例中,您没有包括
标记
,但EF会跟踪以前加载的元素以避免数据库查询,而加载的元素包括
标记
。这就是为什么调用
dbContext.Posts.include时,结果包括
标记
属性。