1

私は次のモデルを持っています:

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.

私は何が欠けていますか?

4

1 に答える 1

2

移行によってこの例外がスローされる理由は正確にはわかりませんが、必要な関係が作成されないことは明らかです。2つではなく3つの外部キーが追加されUpた場合のメソッドで確認できます。EFはここで3つの関係を作成し、そのうちの1つはデフォルトのFK名を持っています。Location_ID

その理由は、EFが持っているか、または逆ナビゲーションプロパティとしてEmployee.Location持っているかどうかを知らないためです。Location.EmployeeLocation.LocationEmployees

これは、いずれかのデータ注釈を使用して明示的に定義する必要があります。

public class Employee
{
    //...

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

...またはFluentAPIを使用:

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);

HasOptional2番目の関係の代わりに使用したことに注意してください。つまり、モデルHasRequiredのFKをLocationnull許容にする必要があります。

public int? EmployeeID { get; set; }

Employee有効な順序がなく、Locationエンティティは相互に依存しているため、データベースに挿入される可能性があるため、両方の関係は必要ありません。

または、ビジネス要件により適している場合はint? LocationID、オプションで他の関係を作成することもできます。Employee

于 2013-03-06T20:50:15.833 に答える