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

问题描述 投票:0回答:1

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

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

c# .net asp.net-mvc entity-framework asp.net-core
1个回答
1
投票

既然你提到你正在使用ASP.NET Core,我假设你也在使用EF Core。不同之处在于,当您在EF Core中拥有多对多关系时,您还需要在代码上创建“链接”实体。在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

© www.soinside.com 2019 - 2024. All rights reserved.