C# .Net核心EF,将记录保存到多对多类型表
我是EF和.NETCore的新手,在我的项目中,我遇到了多对多关系的问题。我使用microsoft文档设置关系,但插入任何数据时遇到问题。该项目是一个看板,我正在尝试建立用户和任务之间的关系。它们都已经存在。目标是创建一个具有userId和taskId的表。以下是我的模型: 看板任务模型: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]
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 Sochackidb
是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);