【发布时间】:2020-09-21 22:39:21
【问题描述】:
This answer 表示防止公开访问修改集合内容的最佳方法是仅公开集合的可枚举。
但是,我认为在使用 Entity Framework 来处理来自后备数据库的集合时这是不可能的,因为这会调用空构造函数并分配属性。
有没有办法解决这个问题?
【问题讨论】:
标签: c# entity-framework collections
This answer 表示防止公开访问修改集合内容的最佳方法是仅公开集合的可枚举。
但是,我认为在使用 Entity Framework 来处理来自后备数据库的集合时这是不可能的,因为这会调用空构造函数并分配属性。
有没有办法解决这个问题?
【问题讨论】:
标签: c# entity-framework collections
不具体。我使用的模式是将 setter 标记为 internal 并使用公共 mutator 方法来处理更新。这并不限制对实体集合之类的修改(至少需要为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 方法没有被使用,如果他们偏离了模式,就向其他开发人员提出这个问题。 mutators 的好处是它确保提供所需的一切,因此可以信任生成的对象是完整且有效的。它不会强制开发人员使用 mutator 方法,但它可以让他们不必担心不完整的状态,也不必解释为什么他们选择不使用它。尝试严格执行模式可能很困难,最终可能会使您的代码库变得不灵活,并错过像 EF 这样的技术可以提供的许多好处。应根据其自身的优点来推广良好的模式,使开发人员的生活更轻松。
最终,我要避免的关键是不要将实体传递到负责 DbContext 范围的代码的边界之外。 IE。如果我正在处理一个表示层和一个服务层,其中服务通过 EF 实体与域交互,那么该服务不会将实体传递给表示。 (可能希望最终操纵域)相反,可以为表示层提供具有更严格约束的 POCO 视图模型或 DTO,然后将它们传递回服务以处理实体。这样,可以在不影响 EF 功能的情况下更严格地限制实体边界之外。 (即利用 Linq 表达式中的导航属性)
【讨论】: