我可以仅使用ID分配多对多关系吗?

时间:2018-03-01 15:09:10

标签: c# .net asp.net-mvc entity-framework asp.net-core

我正在使用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)
}

必须有更好的方法,对吗?如何在不从数据库中提取所有内容的情况下分配收件人?或者至少只做一次请求?

1 个答案:

答案 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; }
}

这将相应地填充多对多表:

enter image description here