我正在使用asp.net mvc核心和entityframework构建一个web api。
我有两个对象,它们之间有多对多的关系。
class User
{
public string ID { get; set; }
public List<Message> Inbox { get; set; }
}
class Message
{
public int ID { get; set; }
public List<User> Recipients { get; set; }
}
要创建新消息,客户端会将JSON发送到我的控制器,其结构如下:
// POST /api/message
{
body: "...", // the body and other properties of the message
recipients: ["user1", "user2"] // a list of the IDs of the recipients of this message
}
所以基本上我需要创建一个新的Message
对象,并根据我在JSON中收到的用户ID分配其Recipients
属性。
到目前为止,我从数据库中提取每个User
对象以将其分配给我的Message
,但这看起来像是浪费资源。
foreach (var userId in json.recipients)
{
var userObject = _dbContext.Users.Find(userId);
message.Recipients.Add(userObject)
}
必须有更好的方法,对吗?如何在不从数据库中提取所有内容的情况下分配收件人?或者至少只做一次请求?
答案 0 :(得分:1)
由于您提到您正在使用ASP.NET Core,我假设您也在使用EF Core。不同之处在于,当您在EF Core中拥有多对多关系时,您需要创建&#34;链接&#34;实体也在代码上。在EF6中,您不需要明确拥有该实体。无论如何,这是你能做的:
创建链接实体:
public class MessageRecipients
{
public int UserId { get; set; }
public User User { get; set; }
public int MessageId { get; set; }
public Message Message { get; set; }
}
配置它们:
modelBuilder.Entity<MessageRecipients>()
.HasKey(bc => new { bc.UserId, bc.MessageId });
modelBuilder.Entity<MessageRecipients>()
.HasOne(bc => bc.User)
.WithMany(b => b.Messages)
.HasForeignKey(bc => bc.UserId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<MessageRecipients>()
.HasOne(bc => bc.Message)
.WithMany(c => c.Recipients)
.HasForeignKey(bc => bc.MessageId)
.OnDelete(DeleteBehavior.Restrict);
然后在POST
消息中,您可以执行此操作:
[HttpPost]
public async Task<IActionResult> PostMessage([FromBody] MessageViewModel viewModel)
{
var message = new Message
{
MessageBody = viewModel.MessageBody,
Recipients = viewModel.Users.Select(c => new MessageRecipients { UserId = c}).ToList()
};
_context.Messages.Add(message);
await _context.SaveChangesAsync();
return Ok();
}
public class MessageViewModel
{
public string MessageBody { get; set; }
public IEnumerable<int> Users { get; set; }
}
这将相应地填充多对多表: