【问题标题】:Linq Any() side effects with Entity Framework实体框架的 Linq Any() 副作用
【发布时间】:2017-06-16 13:10:13
【问题描述】:

我目前正在重构一些使用实体框架的代码。

我无法真正弄清楚为什么有人叫Entities.Any(),它看起来很随机,但评论说它用于覆盖延迟加载的值。调用Any() 不应该修改底层集合,这对我来说仍然没有意义。

我应该放心删除此声明吗?

代码如下所示:

class MyEFObject {

    public virtual ICollection<Entity> Entities { get; set; }

    public void SetEntities(ICollection<Entity> entities)
    {
        // [...]

        Entities.Any(); // to override lazyloaded values
        Entities = entities.Where(a => a.MyEFObjectId == Id).ToList();

        // [...]
    }

 }

当然没有测试,所以我无法验证预期的行为是什么。

【问题讨论】:

  • Entities 似乎是一个内存集合,即将被替换。 Any() 只会检查该集合中是否至少有一项(然后丢弃结果)。我看不出它可能有任何影响。
  • 我不会删除该代码。 Any 在这里不是必需的(GC.KeepAlive(Entities); 或类似的假方法会产生相同的效果) - 必需是调用 Entities 属性 getter
  • @Ivan Stoev 你能解释一下为什么我们要在这种情况下调用实体 getter 吗?
  • 如果对象被 EF 上下文更改跟踪器跟踪,在替换之前确保从数据库加载集合(即获取原始值)很重要。这允许 EF 检测添加/删除/更新操作。

标签: c# entity-framework linq refactoring


【解决方案1】:

Any() 只会检查集合中是否有一个或多个项目与给定的谓词匹配。如果没有谓词(如您的情况),它将检查集合中是否至少有一项。

但是,它不会更改您的集合中的任何内容 - 这是我认为同事想要实现的 - 它会强制运行时评估表达式以从数据库中检索值。您可能知道,只要不需要执行返回 IEnumerableIQueryable 的表达式,就不会执行。第一次调用取决于表达式的返回值的表达式将强制执行它,您的同事可能已经看到,然后 SQL 分析器会显示传入的语句。

但是,我看到下面的行调用了ToList(),这也确保了表达式立即执行。所以不,你真的不需要那个Any()

【讨论】:

  • 我同意。我认为将它放在那里没有任何价值。
猜你喜欢
  • 1970-01-01
  • 2014-03-07
  • 2020-12-23
  • 2017-07-07
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多