[英]EF Core 5.0 - Updating many-to-many entities in ASP.NET Core Web API
With EF Core 5.0 Many-to-many relations are introduced. EF Core 5.0 引入了多对多关系。 I'm getting stucked on how to update them through my asp .net api.
我对如何通过我的 asp .net api 更新它们感到困惑。
For One-to-one and One-to-many relations there is a convention by simply adding the property name followed by ID.对于一对一和一对多关系,有一种约定,只需添加属性名称后跟 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; }
}
So a propper POST Request could look like所以适当的 POST 请求看起来像
{
"BlogId": 123,
"Url": "example.com",
"BlogImageID": 42
}
but I could not find out if there is a convention or how it look like for Many-to-many relations但我无法确定是否存在约定或多对多关系的外观
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; }
}
Is there a convention to map the body of a http request to Many-to-many relations using EF 5.0? map http 对使用 EF 5.0 的多对多关系请求的正文是否存在约定?
Consider the following two entities which are in many-to-many relationship -考虑以下两个处于多对多关系的实体 -
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; }
}
When updating the Tags
in a Post
entity, in the most common scenario, a new list of tag Id
s are sent from the client-side, and the request payload will look like -在更新
Post
实体中的Tags
时,在最常见的情况下,从客户端发送一个新的 tag Id
列表,请求有效负载将如下所示 -
{
"id": 123,
"title": "An Awesome Post",
"tags": [2, 7, 13]
}
Typically, you'd want to define a DTO to represent this request object, like -通常,您希望定义一个 DTO 来表示此请求 object,例如 -
public class PostUpdateDTO
{
public int Id { get; set; }
public string Title { get; set; }
public List<int> Tags { get; set; }
}
Then, for the update operation itself, you can do something like -然后,对于更新操作本身,您可以执行类似 -
[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();
}
As you can see, this requires a trip to the database to fetch a list of all available Tag
.如您所见,这需要访问数据库以获取所有可用
Tag
的列表。 If you don't like that and want to skip it, you can try the following approach -如果您不喜欢它并想跳过它,您可以尝试以下方法 -
[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();
}
About that - property name followed by ID :关于那个 -属性名称后跟 ID :
The kind of Id property you are referring to represents a foreign-key.您所指的那种 Id 属性代表外键。 Neither of these two entities contains a foreign-key property, because neither of them depends on the other.
这两个实体都不包含外键属性,因为它们都不依赖于另一个。 A foreign-key implies a parent/child or principal/dependent relationship.
外键表示父/子或委托人/依赖关系。 But when two entities are in many-to-many relation, they are independent of each other.
但是当两个实体处于多对多关系时,它们是相互独立的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.