EF核心一对多关系:ICollection或哈希集?

时间:2019-02-23 10:03:03

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

我正在阅读乔恩·史密斯(Jon P Smith)撰写的“实体框架核心”。 上面写着:

enter image description here

当Hashet是适当的集合类型时,您能否提供一些示例?为什么呢?

1 个答案:

答案 0 :(得分:6)

我个人将collectRedirects(objects) { var promises = objects.map(function(e){ return S3.getObject({ Key: e.Key, Bucket: bucketName }).promise().then(function(result){ return result.foo; // or alternatively (if you want to amend the original object) e.foo = result.foo; return e; }); }); return Promise.all(promises).then(function(values) { console.log(values); return values; }); } 用于普通属性,只是因为它是一个众所周知的接口,具有最小的开销,即,创建ICollection<T>ICollection快得多。您当然可以使用EF Core使用的IList,但是我发现HashSet<T>的设置比HashSet的设置要难一些,ICollection<T>需要List<T>

注意:我没有考虑任何一种的创建速度-之所以这样做是因为“框架设计准则”一书将这作为最佳实践,请参见第250页。

例如,如果使用未初始化的后备字段集合,则必须使用HashSet<T>

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

IEnumerable<T>是一种特殊情况,因为IEnumerable没有AddRemove方法,因此它将集合转换为只读版本。支持字段加上IEnumerable<T>(请参见上面的代码)使您可以“锁定”集合关系,以便只能在类内部进行更改(请参阅我的文章Domain-Driven Design in EF Core)。

当我使用后备字段集合时,我将其保留为未初始化状态,因此它们必须为HashSet<T>。这使我能够检测出何时忘记使用。包括在加载实体时,例如如果我加载没有.Include(p => p.Reviews)的书,然后访问Reviews属性,则会得到空引用异常。这只是一种安全的编程方式。

如果初始化一个后备字段集合,则可以是ICollection等,但是我不建议初始化一个后备字段集合,因为如果您忘记了Include然后将一个项目添加到列表中,这可能会引起问题。采集。在这种情况下,EF Core会删除所有现有评论,并将其替换为您添加的新评论。从EF Core的角度来看,它按照您所说的去做,但是很可能不是您想要的。