[英]EF Core 5.0 - Updating many-to-many entities in ASP.NET Core Web API
EF Core 5.0 引入了多對多關系。 我對如何通過我的 asp .net api 更新它們感到困惑。
對於一對一和一對多關系,有一種約定,只需添加屬性名稱后跟 ID。
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public BlogImage BlogImage { get; set; }
}
public class BlogImage
{
public int BlogImageId { get; set; }
public byte[] Image { get; set; }
public string Caption { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
所以適當的 POST 請求看起來像
{
"BlogId": 123,
"Url": "example.com",
"BlogImageID": 42
}
但我無法確定是否存在約定或多對多關系的外觀
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public ICollection<Tag> Tags { get; set; }
}
public class Tag
{
public string TagId { get; set; }
public ICollection<Post> Posts { get; set; }
}
map http 對使用 EF 5.0 的多對多關系請求的正文是否存在約定?
考慮以下兩個處於多對多關系的實體 -
public class Post
{
public int Id { get; set; }
public string Title { get; set; }
public ICollection<Tag> Tags { get; set; }
}
public class Tag
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Post> Posts { get; set; }
}
在更新Post
實體中的Tags
時,在最常見的情況下,從客戶端發送一個新的 tag Id
列表,請求有效負載將如下所示 -
{
"id": 123,
"title": "An Awesome Post",
"tags": [2, 7, 13]
}
通常,您希望定義一個 DTO 來表示此請求 object,例如 -
public class PostUpdateDTO
{
public int Id { get; set; }
public string Title { get; set; }
public List<int> Tags { get; set; }
}
然后,對於更新操作本身,您可以執行類似 -
[HttpPut]
public async Task Put([FromBody]PostUpdateDTO dto)
{
// fetch existing Post including related Tags
var post = await _DbCtx.Posts
.Include(p => p.Tags)
.FirstOrDefaultAsync(p => p.Id == dto.Post.Id);
// remove all Tags from the existing list
post.Tags.Clear();
// add new Tags to the list whose Ids are sent by the client
// but to identify them you need the list of all available tags
var availableTags = await _DbCtx.Tags.ToListAsync();
foreach (var id in dto.Tags)
{
post.Tags.Add(availableTags.First(p => p.Id == id));
}
// modify properties of Post if you need, like -
// post.Title = dto.Title;
await _DbCtx.SaveChangesAsync();
}
如您所見,這需要訪問數據庫以獲取所有可用Tag
的列表。 如果您不喜歡它並想跳過它,您可以嘗試以下方法 -
[HttpPut]
public async Task Put([FromBody]PostUpdateDTO dto)
{
// fetch existing Post including related Tags
var post = await _DbCtx.Posts
.Include(p => p.Tags)
.FirstOrDefaultAsync(p => p.Id == dto.Post.Id);
// remove Tags which are in the existing Tag list, but not
// in the new list sent by the client
post.Tags.Where(tag => !dto.Tags.Any(id => id == tag.Id))
.ToList().ForEach(tag => post.Tags.Remove(tag));
// add Tags which are in the new list sent by the client, but
// not in the existing Tag list
dto.Tags.Where(id => !post.Tags.Any(tag => tag.Id == id))
.ToList().ForEach(id => post.Tags.Add(new Tag { Id = id }));
// modify properties of Post if you need, like -
// post.Title = dto.Title;
await _DbCtx.SaveChangesAsync();
}
關於那個 -屬性名稱后跟 ID :
您所指的那種 Id 屬性代表外鍵。 這兩個實體都不包含外鍵屬性,因為它們都不依賴於另一個。 外鍵表示父/子或委托人/依賴關系。 但是當兩個實體處於多對多關系時,它們是相互獨立的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.