无法将ApplicationUser字段添加到通过EF Core创建的数据库中的多个记录

时间:2017-10-22 15:19:12

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

我的班级转包商有一个属性ApplicationUser CreatedUser。创建转包商并将其添加到数据库时,我想将当前的IdentityUser存储为CreatedUser。我使用EF Core Migrations来创建我的数据库。在我添加迁移时,默认情况下,CreatedUser作为外键映射到数据库中的CreatedUserId。

当我运行我的应用程序时,登录用户添加的第一个转包商记录正常工作,并且CreatedUserId字段已更新。我的问题是,一旦用户尝试创建第二个转包商记录,我就会收到未捕获的异常。如果我删除更新CreatedUser字段,它工作正常,我可以添加多个转包商记录。

这让我相信我需要在OnModelCreating中添加自己的关系配置来覆盖默认的EF迁移配置?我不确定我需要指定什么,以便Subcontractor数据库表将接受具有相同CreatedUserId字段的多个记录?或者,默认关系是否正确,是否需要在我的create方法中更改某些内容才能修复?

默认情况下,这是EF Core Migrations创建的内容:

modelBuilder.Entity("SubTracker.Data.Models.Subcontractor", b =>
{
   b.HasOne("SubTracker.Data.Models.ApplicationUser", "Approver")
       .WithMany()
       .HasForeignKey("ApproverId");

   b.HasOne("SubTracker.Data.Models.ApplicationUser", "CreatedUser")
        .WithMany()
        .HasForeignKey("CreatedUserId");
});

配对,我的班级是:

 public class Subcontractor
 {
    public long Id { get; set; }
    public string Name { get; set; }
    public string AddressLineOne { get; set; }
    public string AddressLineTwo { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public ApplicationUser CreatedUser { get; set; }
}

在我的控制器中,我的创建方法是:

private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User);

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Name,AddressLineOne,AddressLineTwo,City,State,Zipcode,ContactName,ContactEmail,ContactPhone")] Subcontractor subcontractor)
{
   if (ModelState.IsValid)
   {
     var user = await GetCurrentUserAsync();

     subcontractor.CreatedTimestamp = DateTime.Now;
     subcontractor.UpdatedTimestamp = subcontractor.CreatedTimestamp;
     subcontractor.AnnualSafetyPrequalApproved = false;
     subcontractor.AnnualInsuranceApproved = false;
     subcontractor.Status = "In Process";
     subcontractor.CreatedUser = user;

     _context.Add(subcontractor);

     await _context.SaveChangesAsync();

     return RedirectToAction(nameof(Index));
   }
   return View(subcontractor);
}

我的ApplicationUser类:

public class ApplicationUser : IdentityUser
{
    public string Branch { get; set; }
    public string Area { get; set; }
    public string Title{ get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }        
    public string Role { get; set; }
 }

我有一个单独的DB上下文用于Identity和我的应用程序数据。我为我的应用程序数据配对的DBContext(删除了其他模型类,但没有为ApplicationUser提供任何内容):

public class SubTrackerDbContext : DbContext
{
    public DbSet<Subcontractor> Subcontractors { get; set; }

    public SubTrackerDbContext(DbContextOptions<SubTrackerDbContext> options) : base(options)
    {
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.ConfigureWarnings(warnings => warnings.Ignore(RelationalEventId.QueryClientEvaluationWarning));
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Subcontractor>().ToTable("Subcontractor");        
    }
}

我的身份识别数据库上下文是:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }
}

1 个答案:

答案 0 :(得分:0)

我认为问题是你如何设置类的一部分。

首先,您需要ApplicationUser' in the Subcontractor`类的外键:

public int CreatedUserId { get; set; }
public virtual ApplicationUser CreatedUser { get; set; }

然后(这可选)您的ApplicationUser必须有Subcontractors的集合:

public virtual ICollection<Subcontractor> Subcontractors { get; set; }

在您的create方法上,只需指定用户ID而不是整个用户。