C# .Net核心EF,将记录保存到多对多类型表

C# .Net核心EF,将记录保存到多对多类型表,c#,entity-framework,.net-core,many-to-many,C#,Entity Framework,.net Core,Many To Many,我是EF和.NETCore的新手,在我的项目中,我遇到了多对多关系的问题。我使用microsoft文档设置关系,但插入任何数据时遇到问题。该项目是一个看板,我正在尝试建立用户和任务之间的关系。它们都已经存在。目标是创建一个具有userId和taskId的表。以下是我的模型: 看板任务模型: public class KanbanTask : Entity { public string Title { get; set; } [Required]

我是EF和.NETCore的新手,在我的项目中,我遇到了多对多关系的问题。我使用microsoft文档设置关系,但插入任何数据时遇到问题。该项目是一个看板,我正在尝试建立用户和任务之间的关系。它们都已经存在。目标是创建一个具有userId和taskId的表。以下是我的模型:

看板任务模型:

public class KanbanTask : Entity
    {
        public string Title { get; set; }
        [Required]
        public string Description { get; set; }
        [Required] 
        public string Status { get; set; }
        public int ProgressStatus { get; set; }
        public List<UserTask> UserTask { get; set; }
    }
UserTaskModel:

public class UserTask
    {
        public int UserId { get; set; }
        public User User { get; set; }
        public int KanbanTaskId { get; set; }
        public KanbanTask KanbanTask { get; set; }
    }
我的数据库上下文:

public DbSet<KanbanTask> KanbanTasks { get; set; }
    public DbSet<User> Users { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<UserTask>()
            .HasKey(t => new { t.UserId, t.KanbanTaskId });

        modelBuilder.Entity<UserTask>()
            .HasOne(pt => pt.User)
            .WithMany(p => p.UserTask)
            .HasForeignKey(pt => pt.UserId);

        modelBuilder.Entity<UserTask>()
            .HasOne(pt => pt.KanbanTask)
            .WithMany(t => t.UserTask)
            .HasForeignKey(pt => pt.KanbanTaskId);
    }
}
像这样

var usertask = new UserTask()
                    {
                        KanbanTaskId = taskId,
                        UserId = userId
                    };
db.UserTasks.Add(usertask);
db.SaveChanges();

您需要确保中间实体(UserTask)始终保存两个实体的键,因此我强烈建议在UserTask构造函数中添加该逻辑

public class UserTask
{
    public int UserId { get; set; }
    public User User { get; set; }
    public int KanbanTaskId { get; set; }
    public KanbanTask KanbanTask { get; set; }

 public UserTask() { }

 public UserTask(User user, KanbanTask kanbanTask) 
 {
    KanbanTask = kanbanTask;
    KanbanTaskId = kanbanTask.Id;
    User = user;
    UserId = userId;
  }
}
//

//

我为这个常见问题写了一个例子。在这里,您可以检查我采用的方法,使用一个通用的中间实体类。
我还将它添加到nuget中以重用它,但是您可以按照模式创建自己的实现

您使用的是什么版本的EF和.Net Core?我在这行代码中没有看到PK
.HasKey(t=>new{t.PostId,t.TagId})您的表需要一个PK才能用EF插入其中。您只需要将UserTask添加到更改跟踪器并保存更改。您甚至不必手头有用户和任务实体。@DavidBrowne Microsoft我该怎么做?我的存储库是泛型的,所以我创建了UserTask模型来继承实体模型。然后我使用wait_usertaskrepo.Add(usertask);尝试将数据添加到数据库。这是可行的,但是对于所有对象来说,基中UserTask对象的Id仍然是0。它也没有对我使用的.NETCore3.1和EF3.1.2的用户和看板任务(UserTask类型的列表)进行任何更改。在这种情况下如何设置PK?它应该是UserTask id吗?在这个上下文中,“db”是什么?我是否必须导入AppDbContext和DbSet(与我在存储库中保存更改时使用的相同)?有没有办法将这两行代码移到存储库而不是服务?Upvote,但这不起作用,他没有用于UserTask的
dbset
。他必须将它添加到他的上下文中。是的,UserTask应该有一个dbset,或者您必须调用
db.Set()
。UserTask是模型中的一个实体,因为EF Core不支持没有链接实体的多对多。@IgorCzeszejko Sochacki
db
是DbContext子类型。很明显,你把它藏在了一个普通的存储库后面。
 public async Task<ResultDTO> AssignTaskToUser(int taskId, int userId)
        {
            var result = new ResultDTO()
            {
                Response = null
            };
            try
            {
                var user = await _repo.GetSingleEntity(x => x.Id == userId);
                var kanbanTask = await _taskrepo.GetSingleEntity(y => y.Id == taskId);
                if (user != null && kanbanTask != null)
                {
                    var usertask = new UserTask()
                    {
                        KanbanTaskId = taskId,
                        UserId = userId
                    };
                    kanbanTask.UserTask.Add(usertask);
                    user.UserTask.Add(usertask); 
                    await _repo.Patch(user);
                }
                else
                    result.Response = "Task or user not found";
            }
            catch (Exception e)
            {
                result.Response = e.Message;
                return result;
            }
            return result;
        }
public async Task Patch(T entity)
        {
            _dbSet.Update(entity);
            await _context.SaveChangesAsync();
        }
var usertask = new UserTask()
                    {
                        KanbanTaskId = taskId,
                        UserId = userId
                    };
db.UserTasks.Add(usertask);
db.SaveChanges();
public class UserTask
{
    public int UserId { get; set; }
    public User User { get; set; }
    public int KanbanTaskId { get; set; }
    public KanbanTask KanbanTask { get; set; }

 public UserTask() { }

 public UserTask(User user, KanbanTask kanbanTask) 
 {
    KanbanTask = kanbanTask;
    KanbanTaskId = kanbanTask.Id;
    User = user;
    UserId = userId;
  }
}
                var usertask = new UserTask(user, kanbanTask);
                kanbanTask.UserTask.Add(usertask);
                user.UserTask.Add(usertask); 
                await _repo.Patch(user);