0

Meine Klasse Subcontractor verfügt über die Eigenschaft ApplicationUser CreatedUser. Wenn ein Subunternehmer erstellt und zur Datenbank hinzugefügt wird, möchte ich den aktuellen IdentityUser als CreatedUser speichern. Ich habe EF Core Migrations verwendet, um meine Datenbank zu erstellen. Der CreatedUser wurde der CreatedUserId in der Datenbank standardmäßig als Fremdschlüssel zugeordnet, als ich die Migration hinzugefügt habe.Das Feld ApplicationUser konnte nicht zu mehr als einem Datensatz in der Datenbank hinzugefügt werden, die über EF Core erstellt wurde

Wenn ich meine App ausführe, funktioniert der erste Subunternehmer-Datensatz, der von einem angemeldeten Benutzer hinzugefügt wird, ordnungsgemäß und das CreatedUserId-Feld wird aktualisiert. Mein Problem ist, dass sobald ein Benutzer versucht, einen zweiten Subunternehmer-Datensatz zu erstellen, ich eine nicht abgefangene Ausnahme erhalte. Wenn ich die Aktualisierung des CreatedUser-Feldes entferne, funktioniert es einwandfrei und ich kann mehrere Subunternehmer-Datensätze hinzufügen.

Dies führt zu der Annahme, dass ich meine eigene Beziehungskonfiguration in OnModelCreating hinzufügen muss, um die standardmäßige EF-Migrationskonfiguration zu überschreiben? Ich bin mir jedoch nicht sicher, was ich angeben muss, damit die Subcontractor-Datenbanktabelle mehrere Datensätze mit demselben CreatedUserId-Feld akzeptiert. Oder ist die Standardbeziehung korrekt, und muss ich etwas in meiner create-Methode ändern, um das Problem zu beheben?

Standardmäßig ist es das, was EF Core-Migrationen erstellt:

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"); 
}); 

Gepaart nach unten, meine Klasse ist:

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; } 
} 

In meinem Controller meine Methode erstellen ist:

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); 
} 

Meine AnwendungUser-Klasse:

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; } 
} 

Ich habe einen separaten DB Kontext für Identität und für meine Anwendungsdaten. Meine gepaart unten DbContext (entfernt andere Klassen Modell, aber nichts für ApplicationUser) für meine Anwendungsdaten sind:

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");   
    } 
} 

Meine DB Kontext für Identität ist:

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

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

Hallo, können Sie bitte Ihre Anwendungsklasse sowie Ihre dbcontext-Klasse hinzufügen? Außerdem bin ich nie auf EF Core gestoßen, der Mapping für Sie erstellt. –

+0

Ich habe den ursprünglichen Beitrag hinzugefügt. Vielen Dank. – billygrow

Antwort

0

Ich denke, das Problem ist ein Teil davon, wie Sie legen die Klassen fest.

Zuerst müssen Sie einen Fremdschlüssel für die ApplicationUser' in the Subcontractor` Klasse:

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

Dann (und dies ist optional) Ihre ApplicationUser eine Sammlung von Subcontractors haben muss:

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

Auf Ihrem erstellen Methode geben Sie einfach die Benutzer-ID nicht den gesamten Benutzer an.

+0

Danke Cristian! Das hat den Trick gemacht. Die einzige Sache, die ich hinzufügen musste, war die Datenannotation [InverseProperty ("CreatedUser")] über der Subcontractors-Auflistung in meiner ApplicationUser-Klasse. Danke nochmal. – billygrow

Verwandte Themen