2013-03-06 126 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