应用程序用户和其他表(实体)之间的关系



我正在尝试将应用程序用户与UserTask应用程序表相关联。但是我得到了下面的错误

InvalidOperationException:无法确定由"UserTask"类型的导航属性"ApplicationUser.UserTask"表示的关系。手动配置关系,或使用"[NotMapped]"特性或使用"OnModelCreating"中的"EntityTypeBuilder.ignore"忽略此属性

我使用NetCore 2.0.3

public class UserTask
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserTaskID { get; set; }
public string Description { get; set; }
[ForeignKey("OwnerUserID")]
public string TaskOwnerId { get; set; }
[ForeignKey("ExecutorUserID")]
public string TaskExecutorId { get; set; }
public virtual ApplicationUser OwnerUserID { get; set; }
public virtual ApplicationUser ExecutorUserID { get; set; }
}

public class ApplicationUser : IdentityUser
{
[ForeignKey("UserTaskID")]
public int UserTaskID { get; set; }
public UserTask UserTask { get; set; }
}

控制器

public IActionResult Create()
{
ViewData["TaskOwnerId"] = new SelectList(_userManager.Users.ToList(), "Id", "Name");
ViewData["TaskExecutorId"] = new SelectList(_userManager.Users.ToList(), "Id", "Name");
return View();
}
// POST: UserTasks/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for 
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("UserTaskID,Description,TaskOwnerId,TaskExecutorId")] UserTask userTask)
{
if (ModelState.IsValid)
{
_context.Add(userTask);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["TaskOwnerId"] = new SelectList(_userManager.Users.ToList(), "Id", "Name", userTask.TaskOwnerId);
ViewData["TaskExecutorId"] = new SelectList(_userManager.Users.ToList(), "Id", "Name", userTask.TaskExecutorId);
return View(userTask);
}

和视图

<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Description" class="control-label"></label>
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="TaskOwnerId" class="control-label"></label>
<select asp-for="TaskOwnerId" class="form-control" asp-items="ViewBag.TaskOwnerId"></select>
</div>
<div class="form-group">
<label asp-for="TaskExecutorId" class="control-label"></label>
<select asp-for="TaskExecutorId" class="form-control" asp-items="ViewBag.TaskExecutorId"></select>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
</div>
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Description" class="control-label"></label>
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="TaskOwnerId" class="control-label"></label>
<select asp-for="TaskOwnerId" class="form-control" asp-items="ViewBag.TaskOwnerId"></select>
</div>
<div class="form-group">
<label asp-for="TaskExecutorId" class="control-label"></label>
<select asp-for="TaskExecutorId" class="form-control" asp-items="ViewBag.TaskExecutorId"></select>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
</div>

你能帮我吗?

像一样尝试

public class UserTask
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserTaskID { get; set; }
public string Description { get; set; }
public ApplicationUser ApplicationUser {get; set; }
}
public class ApplicationUser : IdentityUser
{
public ICollection<UserTask> UserTask { get; set; }
}

在ApplicationDbContext类中

protected override void OnModelCreating(ModelBuilder modelBuilder){
modelBuilder.Entity<ApplicationUser>()
.HasMany(a => a.UserTask)
.WithOne(b => b.ApplicationUser);}

您的问题有两个方面:

  1. ApplicationUser上的UserTask只有一个导航属性。UserTask上的ApplicationUser有两个不同的导航属性,EF不能将两个关系都映射到另一侧的一个外键,所以如果一侧有两个导航属性,那么另一侧也需要两个。例如:

    public UserTask OwnedUserTask { get; set; }
    public UserTask ExecutedUserTask { get; set; }
    
  2. 假设同一实体有两个关系,EF不知道UserTask上的哪个关系映射到ApplicationUser上的哪个,所以您必须配置以下内容:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
    modelBuilder.Entity<ApplicationUser>()
    .HasOne(x => x.OwnedUserTask)
    .WithOne(x => x.OwnerUser);
    modelBuilder.Entity<ApplicationUser>()
    .HasOne(x => x.ExecutedUserTask)
    .WithOne(x => x.ExecutorUser);
    }
    

也就是说,这是一对一的关系实际上没有意义。任务通常是你有多个任务的(如果我只有一个任务要执行就好了!)。因此,这可能是一对多,这将需要您将ApplicationUser更改为类似的内容

public class ApplicationUser : IdentityUser
{
public ICollection<UserTask> OwnedUserTasks { get; set; }
public ICollection<UserTask> ExecutedUserTasks { get; set; }
}

即使进行了更改,仍然存在与以前相同的问题:您有两个到同一实体的关系,所以您必须添加配置来告诉EF如何处理这一问题。只是,现在,您将使用HasMany而不是HasOne:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ApplicationUser>()
.HasMany(x => x.OwnedUserTasks)
.WithOne(x => x.OwnerUser);
modelBuilder.Entity<ApplicationUser>()
.HasMany(x => x.ExecutedUserTasks)
.WithOne(x => x.ExecutorUser);
}

最后,值得一提的是,您可以在关系的任何一方配置它。换句话说,你可以先做Entity<UserTask>,然后再做HasOne(x => x.OwnerUser).WithMany(x => x.OwnedUserTasks)。走哪条路完全取决于你。

相关内容

  • 没有找到相关文章

最新更新