2013-03-06 167 views
1

我有foloowing型號:實體框架的關係問題

public class Employee 
    { 
     public int ID { get; set; } 
     public string name { get; set; } 
     public int LocationID { set; get; } 

     public virtual Location Location { set; get; } 

    } 
    public class Location { 

     public int ID { set; get; } 
     public string NAME { set; get; } 
     public virtual ICollection<Employee> LocationEmployees { get; set; } 

    } 

基本上僱員所屬的位置和位置有很多的員工。我想向位置模型添加一個名爲位置聯繫人的列,該列將是一個員工ID。我試圖通過代碼第一次遷移來添加它,但它不會產生預期的結果。

添加的列

public class Employee 
    { 
     public int ID { get; set; } 
     public string name { get; set; } 
     public int LocationID { set; get; } 

     public virtual Location Location { set; get; } 

    } 
    public class Location { 

     public int ID { set; get; } 
     public string NAME { set; get; } 

     public int EmployeeID { get; set; } 

     public virtual Employee Employee { get; set; } 
     public virtual ICollection<Employee> LocationEmployees { get; set; } 

    } 

遷移文件生成:

public override void Up() 
     { 
      DropForeignKey("dbo.Employees", "LocationID", "dbo.Locations"); 
      DropIndex("dbo.Employees", new[] { "LocationID" }); 
      RenameColumn(table: "dbo.Employees", name: "LocationID", newName: "Location_ID"); 
      AddColumn("dbo.Locations", "EmployeeID", c => c.Int(nullable: true)); 
      AddForeignKey("dbo.Employees", "Location_ID", "dbo.Locations", "ID"); 
      AddForeignKey("dbo.Employees", "LocationID", "dbo.Locations", "ID", cascadeDelete: false); 
      AddForeignKey("dbo.Locations", "EmployeeID", "dbo.Employees", "ID", cascadeDelete: false); 
      CreateIndex("dbo.Employees", "Location_ID"); 
      CreateIndex("dbo.Employees", "LocationID"); 
      CreateIndex("dbo.Locations", "EmployeeID"); 
     } 

     public override void Down() 
     { 
      DropIndex("dbo.Locations", new[] { "EmployeeID" }); 
      DropIndex("dbo.Employees", new[] { "LocationID" }); 
      DropIndex("dbo.Employees", new[] { "Location_ID" }); 
      DropForeignKey("dbo.Locations", "EmployeeID", "dbo.Employees"); 
      DropForeignKey("dbo.Employees", "LocationID", "dbo.Locations"); 
      DropForeignKey("dbo.Employees", "Location_ID", "dbo.Locations"); 
      DropColumn("dbo.Locations", "EmployeeID"); 
      RenameColumn(table: "dbo.Employees", name: "Location_ID", newName: "LocationID"); 
      CreateIndex("dbo.Employees", "LocationID"); 
      AddForeignKey("dbo.Employees", "LocationID", "dbo.Locations", "ID", cascadeDelete: false); 
     } 

我收到此錯誤:

System.Data.SqlClient.SqlException (0x80131904): Foreign key 'FK_dbo.Employees_dbo.Locations_LocationID' references invalid column 'LocationID' in referencing table 'Employees'. 
Could not create constraint. See previous errors. 
    at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) 
    at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) 
    at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 
    at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 
    at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async) 
    at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) 
    at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 
    at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement) 
    at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements) 
    at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, XDocument targetModel, IEnumerable`1 operations, Boolean downgrading, Boolean auto) 
    at System.Data.Entity.Migrations.DbMigrator.ApplyMigration(DbMigration migration, DbMigration lastMigration) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ApplyMigration(DbMigration migration, DbMigration lastMigration) 
    at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId) 
    at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration) 
    at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.RunCore() 
    at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run() 
Foreign key 'FK_dbo.Employees_dbo.Locations_LocationID' references invalid column 'LocationID' in referencing table 'Employees'. 
Could not create constraint. See previous errors. 

我缺少什麼?

回答

2

我不確切知道爲什麼遷移引發此異常,但很明顯它不會創建您想要的關係。您可以在Up方法中看到它,當三個外鍵被添加而不是兩個。 EF在此創建三個關係,其中一個具有默認的FK名稱Location_ID

原因是EF不知道Employee.Location是否具有Location.EmployeeLocation.LocationEmployees作爲逆導航屬性。

你必須以數據註解明確定義此...

public class Employee 
{ 
    //... 

    [InverseProperty("LocationEmployees")] 
    public virtual Location Location { set; get; } 
} 

...或者用流利的API:

modelBuilder.Entity<Location>() 
    .HasMany(l => l.LocationEmployees) 
    .WithRequired(e => e.Location) 
    .HasForeignKey(e => e.LocationID); 

modelBuilder.Entity<Location>() 
    .HasOptional(l => l.Employee) 
    .WithMany() 
    .HasForeignKey(l => l.EmployeeID); 

注意,我在第二次使用HasOptional代替HasRequired這意味着您還必須在您的Location型號中使FK可以爲空:

public int? EmployeeID { get; set; } 

由於不存在有效的排序EmployeeLocation實體可能被插入到數據庫中,因爲它們將互相依賴,所以不需要這兩種關係。

或者,如果您的業務需求更符合您的需求,您還可以在Employee中與int? LocationID建立其他關係。

+0

非常感謝。我希望有一天能夠達到你對EF的理解。 – mpora 2013-03-06 21:55:28