2 回答
TA贡献1794条经验 获得超8个赞
问题是默认的EF Core属性访问方式导致的,ToList()调用这里
public IEnumerable<CaseWorkNote> WorkNotes => _workNotes?.ToList();
不确定您遵循的是哪种类型的方法,但您违反了简单的良好设计规则,即属性(尤其是集合类型)不应在每次获取时分配。不仅因为它效率低下,而且还允许像 EF Core 这样的“智能”客户端检测实际类型,并在加载相关数据List时尝试使用它来添加项目。
实际上,对于这种类型的实现,他们正在添加到一个被丢弃的列表中,换句话说——无处可去。因此 EF Core 加载相关数据/导航属性修复不起作用,这也可能影响更改跟踪器并导致奇怪的行为。
要解决 EF Core 问题,您应该将 EF Core 配置为直接使用支持字段。最简单的方法是在覆盖内全局设置它OnModelCreating:
modelBuilder.UsePropertyAccessMode(PropertyAccessMode.Field);
它也可以针对每个实体或每个实体属性进行设置,但我会建议以上内容,而且 EF Core 3.0 中的预期变化之一是默认使用支持字段。
不管怎样,现在问题就解决了。
不过,最好遵循良好做法。该_workNotes成员应使用初始化程序或在类构造函数中进行初始化,属性获取器应直接返回它。如果想法是阻止调用者通过强制转换结果来访问私有成员,那么还有其他方法可以阻止不克隆集合内容的方法。例如:
//Aggregated entity
private readonly HashSet<CaseWorkNote> _workNotes = new HashSet<CaseWorkNote>();
public IEnumerable<CaseWorkNote> WorkNotes => _workNotes.Select(e => e);
//
无论是否保留导航属性的当前实现,都必须让EF Core 直接使用支持字段。
TA贡献1884条经验 获得超4个赞
添加外键属性CaseId。还添加了Virtual关键字。
public class CaseWorkNote : FullAuditedEntity
{
[ForeignKey("CaseId")]
[Required]
public virtual Case Case { get; private set; }
public virtual Guid CaseId { get; private set; } /* Added */
[Required]
public virtual string Text { get; set; }
private CaseWorkNote() : base() { }
public static CaseWorkNote Create(Case kase, string text)
{
return new CaseWorkNote()
{
Case = kase,
Text = text
};
}
}
- 2 回答
- 0 关注
- 182 浏览
添加回答
举报