C# 添加到聚合根目录时未保存子实体
当我保存更改时,一切看起来都很好。已正确创建CaseWorkNote实体并将其添加到workNotes集合(Case实体的属性)。 当CurrentUnitOfWork调用DbContext->SaveChanges()时,我看到我的实体已添加状态 最后,没有任何内容保存到数据库中 我在代码中遗漏了什么,或者我做错了什么 下面是我的代码和带有跟踪实体的屏幕截图 型号:C# 添加到聚合根目录时未保存子实体,c#,entity-framework-core,aspnetboilerplate,C#,Entity Framework Core,Aspnetboilerplate,当我保存更改时,一切看起来都很好。已正确创建CaseWorkNote实体并将其添加到workNotes集合(Case实体的属性)。 当CurrentUnitOfWork调用DbContext->SaveChanges()时,我看到我的实体已添加状态 最后,没有任何内容保存到数据库中 我在代码中遗漏了什么,或者我做错了什么 下面是我的代码和带有跟踪实体的屏幕截图 型号: 公共类案例:FullAuditedAggregateRoot { [必需] 公共案例类型{get;set;} [必需] 公共字符
公共类案例:FullAuditedAggregateRoot
{
[必需]
公共案例类型{get;set;}
[必需]
公共字符串主题{get;set;}
公共字符串描述符{get;set;}
//聚合实体
私有HashSet\u工作注释;
public IEnumerable WorkNotes=>_WorkNotes?.ToList();
//
公共案例注释AddNote(字符串文本)
{
如果(_workNotes为空)
{
_workNotes=newhashset();
}
CaseWorkNote workNote=CaseWorkNote.Create(这个,文本);
_工作笔记。添加(工作笔记);
返回工作通知单;
}
}
公共类案例工作说明:完整审核性
{
[外国钥匙(“CaseId”)]
[必需]
公案{get;private set;}
[必需]
公共字符串文本{get;set;}
private CaseWorkNote():base(){}
公共静态CaseWorkNote创建(Case-kase,字符串文本)
{
返回新案例注释()
{
Case=kase,
文本=文本
};
}
}
DBcontext:
公共类testDbContext:AbpZeroDbContext
{
公共数据库集案例{get;set;}
公共DbSet CaseWorkNotes{get;set;}
公共testDbContext(DbContextOptions选项)
:base(选项){}
公共覆盖int SaveChanges()
{
//这里我看到state=“Added”的CaseWorkNote实体
var entries=this.ChangeTracker.entries();
foreach(条目中的var项)
{
WriteLine(“状态:{0},类型:{1}”,item.State.ToString(),item.Entity.GetType().FullName);
}
返回base.SaveChanges();
}
}
应用服务类别:
公共类CaseAppService:AsyncCrudAppService、ICaseAppService
{
//为简洁起见,请删除
...
//
公共异步任务AddWorkNote(CreateUpdateCaseWorkNoteDto输入)
{
var kase=wait this.GetEntityByIdAsync(input.CaseId);
kase.AddNote(input.Text);
CurrentUnitOfWork.SaveChanges();
}
受保护的重写异步任务GetEntityByIdAsync(Guid id)
{
var kase=等待存储库
.GetAlling包括(c=>c.WorkNotes)
.FirstOrDefaultAsync(c=>c.Id==Id);
if(kase==null)
{
抛出新EntityNotFoundException(typeof(Case),id);
}
返回kase;
}
公共异步任务GetWorkNotes(EntityDto实体)
{
var kase=wait this.GetEntityByIdAsync(entity.Id);
返回新的ListResultTo(MapToEntityDto(kase.WorkNotes.ToList());
}
}
谢谢
添加外键属性
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
};
}
}
该问题是由默认EF Core属性访问模式和
ToList()
此处调用引起的
public IEnumerable<CaseWorkNote> WorkNotes => _workNotes?.ToList();
它也可以按实体或实体属性设置,但我建议如上所述,此外,EF Core 3.0的预期变化之一是
不管怎样,现在这个问题将得到解决
不过,最好还是遵循良好的做法。\u workNotes
成员应该用初始值设定项或类内构造函数初始化,属性getter应该直接返回它。如果想法是通过强制转换结果来阻止调用者访问私有成员,那么还有其他方法可以防止不克隆集合内容的行为。例如:
//Aggregated entity
private readonly HashSet<CaseWorkNote> _workNotes = new HashSet<CaseWorkNote>();
public IEnumerable<CaseWorkNote> WorkNotes => _workNotes.Select(e => e);
//
//聚合实体
private readonly HashSet_workNotes=new HashSet();
public IEnumerable WorkNotes=>\u WorkNotes.Select(e=>e);
//
无论您是否保留导航属性的当前实现,都必须让EF Core直接使用支持字段。尝试将其保存在正常的ApplicationService(而不是AsyncCrudAppService)中,以便查看AsyncCrudAppService中是否存在问题,这是一个多么详细的答案。我真的很感激你花时间解决我的问题。回答您的问题(“您采用的是哪种方法”)。我遵循了一个例子。是的,你的提示解决了这个问题。非常感谢。
//Aggregated entity
private readonly HashSet<CaseWorkNote> _workNotes = new HashSet<CaseWorkNote>();
public IEnumerable<CaseWorkNote> WorkNotes => _workNotes.Select(e => e);
//