Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Entity Framework - One-to-One - ReferentialConstraint è mappato a una colonna generata dall'archivio

Per convenzione EF6 rappresenta le relazioni uno-a-uno utilizzando il cosiddetto Associazione chiave primaria condivisa , dove la PK dell'entità dipendente funge anche da FK per l'entità principale.

Nel tuo caso, considera Account.Id essere l'FK per Customer e poiché viene generato automaticamente, ottieni l'eccezione in questione.

Il problema aggiuntivo è che EF6 non supporta la relazione uno-a-uno con la proprietà FK esplicita (non esiste HasForeignKey API fluente simile alle relazioni uno-a-molti).

Quindi devi rimuovere AccountId proprietà dal modello e lasciare solo la proprietà di navigazione. Inoltre, sebbene non strettamente necessario, sarebbe bene seguire le convenzioni di denominazione e chiamarlo semplicemente Account anziché AccountValue .

In altre parole, sostituisci

[Column("CUSTOMER_ID")]
public int? CustomerId { get; set; }

public virtual Customer CustomerValue { get; set; }

con

public virtual Customer Customer { get; set; }

Il nome della colonna FK può essere specificato utilizzando il MapKey API fluente:

modelBuilder.Entity<Customer>()
    .HasRequired(c => c.Account)
    .WithRequiredPrincipal(a => a.Customer)
    .Map(m => m.MapKey("CUSTOMER_ID")); // <--

E il gioco è fatto.

Ora il seguente inserisce correttamente prima un nuovo Customer e poi un nuovo Account facendo riferimento ad esso:

var account = new Account
{
    AccountNumber = "00123456",
    Customer = new Customer { FirstName = "Joe" }
};
db.Accounts.Add(account);
db.SaveChanges();