Sto usando il codice EF6 prima e ho una classe User
che deve avere connessioni in entrata e in uscita con altri utenti. Una connessione ha anche proprietà, quindi ho anche una classe Connections
.
public class User
{
public int ID { get; set; }
// Other properties removed here to keep it simple
[InverseProperty("SourceUser")]
public virtual ICollection<Connection> OutgoingConnections { get; set; }
[InverseProperty("DestUser")]
public virtual ICollection<Connection> IncomingConnections { get; set; }
}
public class Connection
{
public int ID { get; set; }
// Other properties removed here to keep it simple
[InverseProperty("OutgoingConnections")]
public User SourceUser { get; set; }
[InverseProperty("IncomingConnections")]
public User DestUser { get; set; }
}
Sto ricevendo il seguente errore durante l'aggiornamento del mio database. Inizialmente non avevo gli attributi InverseProperty
, quindi posso capire perché EF non sapeva cosa fare in quel caso. La documentazione suona come questi attributi sono ciò che voglio però - ma non funziona ancora. Forse sto fraintendendo però.
Voglio finire con una tabella Users
e una tabella Connections
cui la tabella Connections
ha ID
, SourceUserID
, DestUserID
(ovviamente con vincoli FK).
Qualche idea?
Specificare il flag '-Verbose' per visualizzare le istruzioni SQL applicate al database di destinazione. Applicazione di migrazioni esplicite: [201411192045091_InitialCreate]. Applicazione della migrazione esplicita: 201411192045091_InitialCreate. System.InvalidOperationException: Sequence contiene più di un elemento corrispondente su System.Linq.Enumerable.SingleOrDefault [TSource] (origine IEnumerable
1 source, Func
predicato1 source, Func
2) su System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer. <> C__DisplayClass250.b__247 ( <> f__AnonymousType2b2 <>h__TransparentIdentifier242) at System.Linq.Enumerable.WhereSelectEnumerableIterator
2.MoveNext ()
a System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()
1..ctor (
at System.Collections.Generic.List1 collection)
IEnumerable
at System.Linq.Enumerable.ToList[TSource](IEnumerable1 collection)
1 source) su System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.Diff (origine ModelMetadata, destinazione ModelMetadata, Lazy
at System.Linq.Enumerable.ToList[TSource](IEnumerable1 modificationCommandTreeGenerator, MigrationSqlGenerator migrationSqlGenerator, String sourceModelVersion, String targetModelVersion) at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.Diff(XDocument sourceModel, XDocument targetModel, Lazy
11 modificationCommandTreeGenerator, MigrationSqlGenerator migrationSqlGenerator, String sourceModelVersion, String targetModelVersion) at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.Diff(XDocument sourceModel, XDocument targetModel, Lazy
MigrationSqlGenerator migrationSqlGenerator, String sourceModelVersion, String targetModelVersion) su System.Data.Entity.Migrations.DbMigrator.IsModelOutOfDate (modello XDocument, DbMigration lastMigration) su System.Data.Entity.Migrations.DbMigrator.Upgrade (IEnumerable1 pendingMigrations, String targetMigrationId, String lastMigrationId)
1 PendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable
su System.Data.Entity.Migrations.DbMigrator.UpdateInternal (String targetMigration) su System.Data.Entity.Migrations.DbMigrator. <> c__DisplayClassc.b__b () su System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists (Action mustSucceedToKeepDatabase) su System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists (Action mustSucceedToKeepDatabase) su System.Data.Entity.Migrations.DbMigrator.Update (String targetMigration) su System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update (String targetMigration) a System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run () a System.AppDomain.DoCallBack (CrossAppDomainDelegate callBackDelegate) a System.AppDomain.DoCallBack (CrossAppDomainDelegate callBackDelegate)
su System.Data.Entity.Migrations.Design.ToolingFacade.Run (BaseRunner runner) su System.Data.Entity.Migrations.Design.ToolingFacade.Update (String targetMigration, forza booleana) su System.Data.Entity.Migrations.UpdateDatabaseCommand. <> c__DisplayClass2. <.ctor> b__0 () a System.Data.Entity.Migrations.MigrationsDomainCommand.Execute (comando Action) La sequenza contiene più di un elemento corrispondente
Scusa se l'utilizzo di InverseProperties è un requisito, ma le relazioni possono essere eseguite in questo modo se si dispone della flessibilità necessaria per collegarle in modo diverso.
public class User
{
public int ID { get; set; }
[ForeignKey("ID")]
public virtual ICollection<Connection> OutgoingConnections { get; set; }
[ForeignKey("ID")]
public virtual ICollection<Connection> IncomingConnections { get; set; }
}
public class Connection
{
public int ID { get; set; }
public int SourcerId {get;set;}
public int DestUserId {get;set;}
[ForeignKey("SourcerId")]
public User SourceUser { get; set; }
[ForeignKey("DestUserId")]
public User DestUser { get; set; }
}
quindi è necessario aggiungere configurazioni. Nel mio caso per testare l'ho fatto in override protetto overflow OnModelCreating (DbModelBuilder modelBuilder) nel contesto.
modelBuilder.Entity<User>().HasMany(x=>x.IncomingConnections).WithRequired(x=>x.SourceUser).WillCascadeOnDelete(false);
modelBuilder.Entity<User>().HasMany(x => x.OutgoingConnections).WithRequired(x => x.DestUser).WillCascadeOnDelete(false);