Relazioni nel codice del framework Entity First

ieri ho creato il database in Management Studio e ora voglio crearlo in programma usando EF Code First.

Ecco il link al mio database: http://sofit.miximages.com/c%23/1462037_646961388683482_1557326399_n.jpg

E quello che ho fatto:

public class GameModel { [Key] public int Id { get; set; } public string Name { get; set; } public DateTime CreationTime { get; set; } public DateTime StartTime { get; set; } public DateTime EndTime { get; set; } public string TotalTime { get; set; } public DateTime RouteStartTime { get; set; } public DateTime RouteEndTime { get; set; } public int MaxPlayersPerTeam { get; set; } public int CityId { get; set; } public int CreatorId { get; set; } [InverseProperty("Id")] [ForeignKey("CreatorId")] //public int TeamId { get; set; } //[ForeignKey("TeamId")] public virtual UserModel Creator { get; set; } public virtual CityModel City { get; set; } //public virtual TeamModel WinnerTeam { get; set; } } public class RegionModel { [Key] public int Id { get; set; } public string Name { get; set; } public virtual ICollection Cities { get; set; } } public class CityModel { [Key] public int Id { get; set; } public string Name { get; set; } public int RegionId { get; set; } public virtual RegionModel Region { get; set; } public virtual ICollection Users { get; set; } public virtual ICollection Games { get; set; } } public class UserModel { [Key] public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Login { get; set; } public string Password { get; set; } public string Email { get; set; } public DateTime RegistrationDate { get; set; } public string FacebookId { get; set; } public int CityId { get; set; } public virtual CityModel City { get; set; } public virtual IEnumerable Games { get; set; } } 

Per ora volevo creare 4 tavoli ma ho alcuni problemi … Voglio creare CreatorId in GameModel, ma non funziona … Quando ho scritto UserId invece di CreatorId funzionava (senza [InverseProperty (“Id “)] e [ForeignKey (” CreatorId “)]).

Questo è quello che ottengo:

La vista “L’ID proprietà” non può essere configurato come proprietà di navigazione. La proprietà deve essere un tipo di quadro valido e la proprietà deve avere un getter e un setter non astratto. Per le proprietà della raccolta, il tipo deve implementare ICollection dove T è un tipo di quadro valido. ‘ o il suo master non è stato trovato o nessun motore di visualizzazione supporta le posizioni ricercate.

modifica: l’ho cambiato così:

  public int CityId { get; set; } public int CreatorId { get; set; } [ForeignKey("CityId")] public virtual CityModel City { get; set; } [ForeignKey("CreatorId")] public virtual UserModel Creator { get; set; } 

E c’è un altro problema.

La vista “L’introduzione del vincolo FOREIGN KEY” FK_dbo.UserModels_dbo.CityModels_CityId “nella tabella” UserModels “può causare cicli o più percorsi a cascata. Specificare ON DELETE NO ACTION o ON UPDATE NO ACTION o modificare altri vincoli FOREIGN KEY. Imansible creare un vincolo. Vedi errori precedenti. ‘ o il suo master non è stato trovato o nessun motore di visualizzazione supporta le posizioni ricercate.

E non ho idea di come risolverlo.

InversePropertyAttribute specifica, quale proprietà di navigazione deve essere utilizzata per quella relazione.

Una proprietà di navigazione deve essere di tipo entity framework (i tipi dichiarati nel modello, GameModel ad esempio) o qualche tipo che implementa ICollection , dove T deve essere un tipo di entity framework. UserModel.Id è un int , che chiaramente non soddisfa questa condizione.

Quindi, la proprietà inversa di GameModel.Creator potrebbe essere UserModel.Games se hai cambiato il tipo in ICollection , oppure non è stato specificato. Se non si specifica una proprietà inversa, EF cercherà di risolvere tutto da solo (in questo caso riconoscerà correttamente GameModel.Creator come proprietà di navigazione, ma UserModel.Games molto probabilmente UserModel.Games un’eccezione, poiché è né un tipo di entity framework, né implementa ICollection con T come tipo di quadro, né è un tipo primitivo dal punto di vista del database). Tuttavia, la magia di work-everything-out-by-itself di EF non riesce a far fronte troppo bene a più relazioni tra gli stessi tipi di entity framework, che è quando è necessario l’ InversePropertyAttribute .

Un rapido esempio che dimostra il problema:

 class SomePrettyImportantStuff { [Key] public int ID { get; set; } public int OtherId1 { get; set; } public int OtherId2 { get; set; } [ForeignKey("OtherId1")] public virtual OtherImportantStuff Nav1 { get; set; } [ForeignKey("OtherId2")] public virtual OtherImportantStuff Nav2 { get; set; } } class OtherImportantStuff { [Key] public int ID { get; set; } public virtual ICollection SoldStuff { get; set; } public virtual ICollection BoughtStuff { get; set; } } 

Qui, EF sa che deve generare 2 FK da SomePrettyImportantStuff a OtherImportantStuff con i nomi Id1 e Id2 , ma non ha modo di sapere quale degli ID si riferisce all’ quadro dalla quale è stato venduto e quale è quello che è stato acquistato a partire dal.

Modifica: come risolvere il problema di riferimento ciclico

Per risolvere questo problema, la tua class di contesto dovrebbe sovrascrivere OnModelCreating e configurare le chiavi esterne che non dovrebbero sovrapporsi di conseguenza, in questo modo:

 protected override void OnModelCreating(DbModelBuilder builder) { builder.Entity().HasMany(c => c.Users).WithRequired(u => u.City) .HasForeignKey(u => u.CityId).WillCascadeOnDelete(value: false); // Add other non-cascading FK declarations here base.OnModelCreating(builder); }