![](/img/trans.png)
[英]EF Core NullReferenceException on Related Navigation Property
[英]EF Core - Removing a related entity from collection navigation property does not update database
我試圖理解這句話:
默認情況下,對於必需的關系,將配置級聯刪除行為,並且將從數據庫中刪除子級/從屬實體。
在EF Core的此Microsoft文檔的“刪除關系”段落中找到: https : //docs.microsoft.com/zh-cn/ef/core/saving/related-data#removing-relationships
在.Net Core API上,其博客和帖子模型如下
public class Blog
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int BlogId { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
public class Post
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int PostId { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
當我通過ID通過ID檢索博客時
[HttpGet("{id}")]
public async Task<IActionResult> GetBlog([FromRoute] int id)
{
return await context.Blog.Where(b => b.BlogId == id)
.Include(b => b.Posts).FirstOrDefaultAsync();
}
我收到JSON
{
"BlogId": 1,
"Posts": [
{
"PostId": 1
},
{
"PostId": 2
}
]
}
當我發回API時,更新后的以下JSON將保留在數據庫中
{
"BlogId": 1,
"Posts": [
{
"PostId": 2
}
]
}
至
[HttpPut("{id}")]
public async Task<IActionResult> PutBlog([FromRoute] int id, [FromBody] Blog blog)
{
this.context.Update(blog);
await this.context.SaveChangesAsync();
return this.Ok();
}
一切運行正常,但沒有任何條目被修改。
由於需要從帖子到博客的關系,並且已從Blog的collection-of-posts屬性中刪除了相關的帖子,因此是否應該從數據庫中刪除PostId = 1的帖子?
真正令我困惑的是,只要我在博客和帖子之間使用多對多關系,而沒有在邏輯上進行任何其他更改,則實際上會刪除表Blog_Post中PostId = 1的條目。
Update
僅關聯實體並將所有屬性標記為已修改。 AFAIK它不會層疊下來,也不會影響子集合。
通常,您應避免將實體與Web客戶端之間來回傳遞。 如果您接受Web客戶端的實體,則很簡單的事情就是找到將已修改的實體傳遞給服務器的調用,應用斷點,並在繼續之前使用調試器修改內容。 如果服務器僅將實體附加到上下文並保存更改,則可以按照應用程序不允許的方式修改數據。 它還涉及向客戶端發送/從客戶端發送比通常所需更多的信息。
關於刪除孤兒的行為,在修改集合時適用。 您可以找到一個示例來檢測要添加和刪除的實體,並在我對此問題的回復中應用這些更改。
Enity Framework從原則實體到從屬實體刪除相關實體。 在您的案例中,原則是Blog,而Post是從屬實體。 通過刪除Blog相關帖子也應刪除。 您還需要使用外鍵屬性進行修飾,在這種情況下,您的類將如下所示。
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogForeignKey { get; set; }
[ForeignKey("BlogForeignKey")]
public Blog Blog { get; set; }
}
您還需要定義刪除行為,可以使用Fluent API設置來執行此操作,Cascade會刪除相關實體,如果您不想刪除相關實體,請使用ClientSetNull,它將
model.Entity<Post>().HasOne(p => p.Blog).WithMany(b => b.Posts)
.HasForeignKey(p => p. BlogForeignKey)
.OnDelete(DeleteBehavior.Cascade);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.