【问题标题】:EF Core one to many relationships: ICollection or Hashset?EF Core 一对多关系:ICollection 还是 Hashset?
【发布时间】:2019-07-17 08:04:27
【问题描述】:

我正在阅读 Jon P Smith 的“Entity Framework Core in Action”。 上面写着:

当 Hashet 是一个合适的集合类型时,你能提供一些例子吗?为什么?

【问题讨论】:

    标签: .net entity-framework asp.net-core entity-framework-core


    【解决方案1】:

    更新:我刚刚更新完我的书 Entity Framework Core in Action,我做了一些性能测试,结果表明,如果您进行正常查询,HashSet<T> 会更快(即在询问)。这是因为 EF Core 做了一些称为 Identity Resolution 的操作(请阅读 this in one of my articles),这对于非 HashSet 集合来说速度较慢。因此,如果您的收藏中有很多条目,那么HashSet<T> 会更好。

    我个人将ICollection<T> 用于普通属性,只是因为它是一个众所周知的接口,开销最小,即创建ICollectionIList 稍微快一点。你当然可以使用 HashSet<T>,这是 EF Core 使用的,但我发现 HashSetICollection<T> 更难设置,List<T>

    如果您使用未初始化的支持字段集合,您必须使用HashSet<T> 的一个地方 - 请参阅下面的代码:

    private HashSet<Review> _reviews;
    public IEnumerable<Review> Reviews => _reviews?.ToList();
    

    更新:在 EF Core 3 中,必须对未初始化的集合使用 HashSet&lt;T&gt; 的限制已被移除(请参阅 this issue)。您可以使用ICollection&lt;T&gt;List&lt;T&gt; 等。

    IEnumerable&lt;T&gt; 是一个特例,因为IEnumerable 没有AddRemove 方法,它会将集合转换为只读版本。支持字段加上IEnumerable&lt;T&gt;(参见上面的代码)允许您“锁定”集合关系,以便只能从类内部更改它(参见我的文章Domain-Driven Design in EF Core)。

    当我使用支持字段集合时,我将它们设为未初始化,因此它们需要为 HashSet&lt;T&gt;。这使我可以检测到何时忘记使用 .Include 加载实体时,例如如果我加载了没有.Include(p =&gt; p.Reviews) 的书,然后访问了Reviews 属性,我会得到一个空引用异常。这只是一种安全的编程方式。

    如果您初始化支持字段集合,那么它可以是ICollection 等,但我不建议初始化支持字段集合,因为如果您忘记包含然后将项目添加到集合中,它可能会导致问题。在这种情况下,EF Core 会删除任何现有的评论并将其替换为您添加的新评论。从 EF Core 的角度来看,它按照您所说的做,但很可能不是您想要的。

    【讨论】:

    • IEnumerable&lt;T&gt; 呢?。
    • 为未命名的IEnumerable&lt;T&gt; 添加了部分
    • 感谢您快速而翔实的回复!您能否详细说明在这种情况下避免使用 Hashset 的原因:但我发现 HashSet 比 ICollection 更难设置,ICollection 需要一个 List
    • @DeivydasVoroneckis。首先我应该说这只是个人喜好,使用HashSet&lt;T&gt; 很可能会更好。我一直将 ICollection&lt;T&gt; 与 EF6 和现在的 EF Core 一起使用。具体但次要的问题是我可以直接从List&lt;T&gt; 分配给ICollection,但对于HashSet&lt;T&gt; 需要new HashSet&lt;T&gt;( ... someList)。如果您在任何地方都使用HashSet&lt;T&gt;,请继续这样做。
    猜你喜欢
    • 2017-10-26
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 2019-04-14
    • 2019-01-19
    • 1970-01-01
    相关资源
    最近更新 更多