C# EF Core-正确的配置是什么?
我有以下型号:C# EF Core-正确的配置是什么?,c#,ef-core-2.2,C#,Ef Core 2.2,我有以下型号: public class Book { public Guid Id { get; set; } public List<IndexPage> IndexPages { get; set; } } public class IndexPage { public Guid Id { get; set; } public List<IndexWord> Words { get; set; } public i
public class Book
{
public Guid Id { get; set; }
public List<IndexPage> IndexPages { get; set; }
}
public class IndexPage
{
public Guid Id { get; set; }
public List<IndexWord> Words { get; set; }
public int IndexType { get; set; }
public Guid BookId { get; set; }
}
public class IndexWord {
public Guid Id { get; set; }
public String Value { get; set; }
public IndexPageId { get; set; }
}
如果书籍更新,索引页将全部替换为一组新的索引页。
如果第一次调用update,则所有都将正常工作并插入行。但是,当第二次调用时,它会引发主键约束异常;这是有道理的,但是我希望删除旧的indexpages,插入新的indexpages。由于主键存在,并且调用了update,而不是Add
复合键背后的原因是一本书只能有一个固定的索引页子集。这也是使用HasPrincipalKey
的原因
仅将IndexPage Id用作配置中的键时。这本书之间的关系是存在的,但它只是不断地在旧的索引页之上插入新的索引页(我猜是因为AsNoTracking?)。
此外,在代码隐藏中,我在书中添加了索引页,但这些索引页最初具有空id。根据
更新
开始跟踪实体。这意味着,如果您修改它,就可以调用DbContext.SaveChanges()
来保存它。如果您对跟踪的实体调用Update
,它会尝试插入它。如果我理解正确,在您尝试更新时,旧的IndexPage
实体不会被新实体替换
您提到您正在对查询使用无跟踪。如果不跟踪查询返回的原始实体,EF Core无法判断该实体是否已被修改。如果希望新的IndexPage
对象替换旧对象,则需要跟踪查询并为关系配置删除行为
您可以查看EF核心文档,以获取有关所需关系和删除行为的参考。请小心在适当的实体上配置这些内容,这样就不会通过删除索引页面
来删除所有内容
允许更改跟踪并配置是否需要关系及其删除行为。这将实现你想要实现的目标
旧的索引页只是没有在数据库中删除,还是旧的索引页也与新的索引页一起保留在书本上?对不起,使用复合键会产生pk约束。使用单个Id作为键,它会将其插入现有行旁边,以便它们保持连接。是否有理由不使用跟踪?如果EF Core没有跟踪查询返回的原始实体,它无法通过使用新的IndexPages进行更新来判断您是否对其进行了修改;我只希望更新后新的索引页存在,旧的行被删除。由于已更新的对象不再有这些行,是否应该删除旧行?
public class BookConfiguration : IEntityTypeConfiguration<Book>
{
public void Configure(EntityTypeBuilder<Book> builder)
{
builder.ToTable("Books");
builder.HasKey(b => b.Id);
builder.HasMany(b => b.IndexPages)
.WithOne()
.HasForeignKey(b => b.BookId);
}
}
public class IndexPageConfiguration : IEntityTypeConfiguration<IndexPage>
{
public void Configure(EntityTypeBuilder<IndexPage> builder)
{
builder.ToTable("IndexPages");
builder.HasKey(ip => new { ip.BookId, ip.IndexType });
builder.HasMany(ip => ip.IndexWords)
.WithOne()
.HasForeignKey(iw => iw.IndexPageId)
.HasPrincipalKey(ip => ip.Id);
builder.HasIndex(ip => ip.Id).IsUnique();
}
}
public class IndexWordConfiguration : IEntityTypeConfiguration<IndexWord>
{
public void Configure(EntityTypeBuilder<IndexWord> builder)
{
builder.ToTable("IndexWords");
builder.HasKey(iw => iw.Id);
builder.Property(iw => iw.Value).IsRequired();
}
}
DbContext.Set<Book>.Update(book);