【问题标题】:EF6: Why Does Count return 0 but Find return an element?EF6:为什么 Count 返回 0 但 Find 返回一个元素?
【发布时间】:2015-06-10 17:33:07
【问题描述】:

在这段代码中

using (var db = new DbPerson())
{
    var b = db.People.Create();
    b.Name = "Homer";

    db.People.Add( b );

    Console.WriteLine( "Count: {0}", db.People.Count() );

    foreach (var bb in db.People)
        Console.WriteLine( bb.Name );

    var fb = db.People.Find( b.Id ); // Id is a GUID generated in the Person ctor
                                     //  NOT a DB-generated Identity.
    Console.WriteLine( "Found: {0}", fb != null );

    db.SaveChanges();

    Console.WriteLine( "Count: {0}", db.People.Count() );
}

输出如下所示:

Count: 0
Found: True
Count: 1

我看到其他关于 Count 的帖子在调用 SaveChanges 之前没有更新。好的,这就是“它的工作方式”。

我的问题具体是这样的:当Count() 返回0 并且枚举器不返回任何元素时,为什么Finddb.People 返回一个对象? FindCount() 不应该采取类似的行为,在返回处于“已添加”状态的实体之前等待 SaveChanges

这是什么原因?我问是因为我正在编写一个轻量级的非 SQL 提供程序,它需要尽可能地反映 EF 的操作。我无法弄清楚是什么逻辑导致 Find 返回一个已添加的元素,而 Count()GetEnumerator() 没有。我需要解决这些情况。

【问题讨论】:

    标签: entity-framework


    【解决方案1】:

    Find() 有一个特殊的特性:它会首先查看 DbContext 中新添加但尚未刷新到数据库中的实体(例如:EntityState.Added 的实体)。

    Count() 并且枚举器将改为查看数据库,在您调用 SaveChanges() 之前,该数据库显然还没有任何内容。

    Background info

    【讨论】:

    • 我完全理解这一点。我的问题是为什么,我还需要在哪里知道上下文的新添加的实体被搜索/包含在哪里?
    • 每次你得到意想不到的结果,我假设?例如,docs 中也解释了这一点:“如果上下文中存在具有给定主键值的实体,则立即返回它而不向商店发出请求。”跨度>
    • 在阅读了DbSet<> 上每个方法的文档,以及测试了诸如在DbSet 上使用Queryable.FirstOrDefaulit 之类的东西之后,我认为这就是答案- Find 方法是唯一的地方它明确指出返回值来自上下文,而不是数据库。 FirstOrDefault 在保存更改之前不会“找到”实体。
    【解决方案2】:

    如果您问为什么它是这样实现的:Find 应该允许您通过 ID 访问不在数据库中的跟踪实体。 Find 是一种相当特殊的方法。也许它也允许检索已删除的实体,文档没有说。 There are other APIs for reaching into the pool of tracked entities as well.

    如果你需要弄乱它,这通常是 EF 使用不当的标志(或黑客攻击的标志)。

    NHibernate 有一个非常有用的Find:它允许您在 访问数据库的情况下获取实体。它返回一个代理。这样,您总是可以传递实体对象,而几乎从不传递 ID。一个不错的抽象。这在 EF 中是不可能的。 Find 进入数据库。

    【讨论】:

    • 我刚刚测试过——一个已被移除的实体(在 SaveChanges 之前,处于“已删除”状态)也会被 Find 返回。
    • 顺便说一句,NHibernate 在另一方面也不错。它会在每次查询之前自动保存所有更改。这样数据库总是同步的,很难区分上下文结果和数据库结果。 NHibernate 的座右铭是坚持无知。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 2019-08-05
    • 2015-06-21
    相关资源
    最近更新 更多