不具体。我使用的模式是将设定者标记为
internal
并使用公共变异器方法来处理更新。这并不限制对实体集合(需要
ICollection<T>
至少),但如果它提供了一个标准且易于遵循的路径,那么相信所有开发人员都会使用它。
收集的模式是:
public virtual ICollection<Child> Children { get; internal set; } = new List<Child>();
没有什么能阻止代码与Children集合进行交互
.Children.Add(new Child { /* ... */ });
但是,如果我的上级班级提供:
public Child AddChild(string Name, DateTime dob /*, ... */)
{
// TODO: Validate passed in parameters, look for duplicates, etc...
var child = new Child{ /* ... */, Parent = this };
Children.Add(child);
return child;
}
…然后很容易在子集合之类的东西上进行查找用法,或者注意到提供的Add方法没有被使用,如果其他开发人员偏离了模式,可以向他们提出这个问题。变异器的好处是,它确保提供所需的一切,这样生成的对象就可以被信任为完整有效的。没有
力
开发人员可以使用mutator方法,但这让他们不用担心不完整的状态,也不用解释为什么他们选择不使用它。试图严格执行一个模式可能很困难,最终可能会使你的代码库变得不灵活,并错过EF等技术可以提供的许多好处。好的模式应该根据其自身的优点来推广,使开发人员的生活更轻松。
最终,我要避免的关键是不要将实体传递到负责Contoso作用域的代码边界之外。即,如果我处理的是表示层和服务层,其中服务通过EF实体与域交互,那么服务不会将实体传递给表示层。(可能希望最终操纵该领域)相反,可以向表示层提供POCO视图模型或DTO,这些模型具有更严格的约束条件,然后将其传递回服务以处理实体。这样,在实体边界之外可以受到更严格的约束,而不会影响EF功能。(即利用Linq表达式中的导航属性)