Quando provo a caricare un'entità figlio dell'entità padre, carica con i valori predefiniti. Se provo a caricare in modo esplicito, il vincolo di eccezione Multiplicity viene violato . Il ruolo 'Association_Customer_Target' della relazione 'CodeFirstNamespace.Association_Customer' ha molteplicità 1 o 0..1. Questa eccezione viene lanciata durante il recupero delle entità figlio di un grafico complesso.
Ho una associazione grafico che ha un'entità figlio Cliente con una relazione di uno a zero o uno e ha un'associazione indipendente . * La chiave primaria * è condivisa . Sto usando EF6. il caricamento lazy è abilitato.
public class Association
{
public virtual long Id { get; set; }
public virtual string ExternalId { get; set; }
public virtual int OrganizationId { get; set; }
public virtual AssociationType AssociationType { get; set; }
public virtual Customer Customer {get; set;}
public Association()
{
Customer = new Customer();
}
}
Classe cliente
public class Customer
{
public virtual long Id { get; set; } //Shared primary key
public virtual ICollection<Item> Items {get; set;}
public virtual ICollection<Complaint> Complaints {get; set;}
public customer()
{
Items = new List<Item>();
Complaints = new List<Complaint>();
}
}
Le mappature sono unidirezionali:
public class AssociationMapping:EntityTypeConfiguration<Association>
{
public AssociationMapping() : base()
{
HasKey(x => x.Id);
Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(x => x.ExternalId).IsRequired();
Property(x => x.OrganizationId).IsRequired();
Property(x => x.AssociationType);
HasOptional(x => x.Customer).WithRequired().WillCascadeOnDelete();
}
}
public class CustomerMapping : EntityTypeConfiguration<Customer>
{
public CustomerMapping ():base()
{
HasKey(x => x.Id);
Property(x => x.Id);
HasMany(x => x.Items)
.WithOptional()
.HasForeignKey(key => key.CustomerId)
.WillCascadeOnDelete();
HasMany(x => x.Complaints)
.WithOptional()
.HasForeignKey(key => key.CustomerId)
.WillCascadeOnDelete();
}
}
Quando carico l'entità dell'associazione viene caricata perfettamente ma l'entità figlio viene caricata con i valori predefiniti quando provo a caricare esplicitamente il cliente e lancia l'eccezione.
var dbassociation = Single<Association>(x => x.OrganizationId== asso.organizationId && x.ExternalId == asso.ExternalId && x.AssociationType == asso.AssociationType);
dbassociation.Customer = Single<Customer>(x => x.id == dbassociation.id);
[Aggiornamento: metodo singolo]
public TEntity Single<TEntity>(System.Linq.Expressions.Expression<Func<TEntity, bool>>criteria) {
return Context.Set<TEntity>().SingleOrDefault(criteria); }
A scopo di test, ho provato a caricare con entusiasmo rimuovendo virtual sulla proprietà Customer nella classe di associazione e ho provato a seguire, ma genera la stessa eccezione
Context.Configuration.LazyLoadingEnabled = false;
Context.Entry<Association>(dbassociation).Reference<Customer>(pa => pa.Customer).Load();
Ho anche provato quale getta la stessa eccezione
var dbassociation = Context.Set<Association>().Include("Customer").SingleOrDefault(x => x.OrganizationId== asso.organizationId && x.ExternalId == asso.ExternalId && x.AssociationType == asso.AssociationType);
Ora sono arrivato alla conclusione che sebbene io usi metodi diversi per recuperare l'eccezione è la stessa cosa. Il problema è con la mappatura, credo. Apprezzo i tuoi commenti e suggerimenti.
Prova a rimuovere
Customer = new Customer();
dal costruttore Association
. L'istanziazione dei riferimenti di navigazione è fonte di problemi noti (in contrasto con l'istanziazione di raccolte di navigazione vuote che va bene). È il motivo per cui ottieni un Customer
con valori predefiniti. Non sono sicuro che spieghi anche l'eccezione, ma immagino che quando l' Association
viene caricata e allegata al contesto insieme al Customer
non inizializzato creato dal costruttore predefinito EF rileva le entità correlate con chiavi non valide: L' Association
che ha ( Presumo) un valore chiave !=0
e il Customer
correlato con una chiave ==0
(perché non è mai stato inizializzato su un altro valore). Tuttavia, in un'associazione di chiavi primarie condivisa i due valori chiave devono corrispondere. Perché non lo fanno, potrebbe causare l'eccezione (tuttavia un'eccezione che non punta molto bene alla radice del problema).
Solo una supposizione.