vogliamo migrare il nostro progetto da Database-First a Code-First. Per questo compito ho usato il codice prima dal generatore di database di Visual Studio. Ho alcune tabelle con PK e FK concatenati. Non posso cambiarli in un semplice "ID", perché c'è un'applicazione legacy che ha bisogno di loro in questo modo. La versione EF è 6.1.3
Quando avvio il mio programma, visualizzo il seguente errore:
(1568,10): errore 3015: problema nella mappatura dei frammenti che iniziano alle righe 1568, 1583: Vincolo della chiave esterna "tblRechnungPosition_tblAngebReches" dalla tabella tblAngebRech (RechNr, RechPosNr, CompanyID) alla tabella tblRechnungPosition (RechNr, CompanyID, PosNr) :: Mappatura insufficiente : La chiave esterna deve essere associata ad alcuni AssociationSet o EntitySet che partecipano a un'associazione di chiavi esterne sul lato concettuale.
Non riesco a capire cosa stia causando l'errore, per me tutte le relazioni sembrano corrette.
Ecco le classi:
public partial class tblAngebRech
{
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int AngebotID { get; set; }
[Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int AngebPosNr { get; set; }
[Key]
[Column(Order = 2)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int RechNr { get; set; }
[Key]
[Column(Order = 3)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int RechPosNr { get; set; }
[Key]
[Column(Order = 4)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CompanyID { get; set; }
public DateTime Timestamp { get; set; }
public virtual tblAngebotPosition tblAngebotPosition { get; set; }
public virtual tblRechnungPosition tblRechnungPosition { get; set; }
}
.
public partial class tblRechnungPosition
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public tblRechnungPosition()
{
tblAngebReches = new HashSet<tblAngebRech>();
tblBeauftReches = new HashSet<tblBeauftRech>();
tblRechPosMitarbs = new HashSet<tblRechPosMitarb>();
}
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int RechNr { get; set; }
[Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CompanyID { get; set; }
[Key]
[Column(Order = 2)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int PosNr { get; set; }
public int PosTypID { get; set; }
public int? StdKeyID { get; set; }
public double Menge { get; set; }
public double Betrag { get; set; }
[Required]
[StringLength(100)]
public string Bezeichnung { get; set; }
public DateTime Timestamp { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<tblAngebRech> tblAngebReches { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<tblBeauftRech> tblBeauftReches { get; set; }
public virtual tblPositionstyp tblPositionstyp { get; set; }
public virtual tblRechnung tblRechnung { get; set; }
public virtual tblStundenKey tblStundenKey { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<tblRechPosMitarb> tblRechPosMitarbs { get; set; }
E questo è protected override void OnModelCreating(DbModelBuilder modelBuilder)
da protected override void OnModelCreating(DbModelBuilder modelBuilder)
modelBuilder.Entity<tblRechnungPosition>()
.HasMany(e => e.tblAngebReches)
.WithRequired(e => e.tblRechnungPosition)
.HasForeignKey(e => new { e.RechNr, e.CompanyID, e.RechPosNr });
Qualsiasi aiuto sarebbe apprezzato.
Prova a regolare manualmente l'ordine delle proprietà FK nel modelbuilder in questo modo:
modelBuilder.Entity<tblRechnungPosition>()
.HasMany(e => e.tblAngebReches)
.WithRequired(e => e.tblRechnungPosition)
.HasForeignKey(e => new { e.RechNr, e.RechPosNr, e.CompanyID });
Ho inviato un bug al team EF 6.x su codeplex. Ecco il link: https://entityframework.codeplex.com/workitem/2947
Se questo non funziona. Prova a modificare il numero di ordine dell'attributo della colonna nella classe tblRechnungPosition su:
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int RechNr { get; set; }
[Key]
[Column(Order = 2)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CompanyID { get; set; }
[Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int PosNr { get; set; }
Nota: hai chiavi esterne composte. In entrambe le classi di tabelle l'ordine delle proprietà deve essere lo stesso all'interno di [Columns(Order = <order number>)]
.