实体框架外键代码优先迁移错误

3

我有一个实体框架类,其中包含两个对另一个对象的引用。

public class Review
{
    [Key]
    public int Id
    {get;set;}

    public int? FeatureId {get;set;}

    public Feature Feature {get;set;}
}

public class Feature
{
    [Key]
    public int Id
    {get;set;}

    public ICollection<Review> Reviews {get;set;}

}

当我使用Add-Migration生成迁移时,这个功能可以正常工作。

现在,我添加了第二个条目。

public class Review
{
    [Key]
    public int Id
    {get;set;}

    public int? FeatureId {get;set;}

    public Feature Feature {get;set;}

    public int? CompareToFeatureId {get;set;}

    public Feature CompareToFeature {get;set;}
}

当我运行迁移时,它会做一些奇怪的事情,比如重命名原始列。
   RenameColumn(table: "dbo.Reviews", name: "FeatureId", newName: "Feature_Id");
   AddColumn("dbo.Reviews", "CompareToFeatureId", c => c.Int());
   AddForeignKey("dbo.Reviews", "FeatureId", "dbo.Features", "Id");
   AddForeignKey("dbo.Reviews", "CompareToFeatureId", "dbo.Features", "Id");
   CreateIndex("dbo.Reviews", "FeatureId");
   CreateIndex("dbo.Reviews", "CompareToFeatureId");

那应该没问题,但当我运行update-database时迁移失败了。
Applying code-based migrations: [201211092218271_Test2].
Applying code-based migration: 201211092218271_Test2.
System.Data.SqlClient.SqlException (0x80131904): Foreign key 'FK_dbo.Reviews_dbo.Features_FeatureId' references invalid column 'FeatureId' in referencing table 'Reviews'.
Could not create constraint. See previous errors.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
   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()
ClientConnectionId:f1573dba-4658-462f-969a-9afbf1e4374a
Foreign key 'FK_dbo.Reviews_dbo.Features_FeatureId' references invalid column 'FeatureId' in referencing table 'Reviews'.
Could not create constraint. See previous errors.

不确定该怎么做,有什么建议吗?

1个回答

4

由于您没有遵循约定(Feature_ID),需要进行一些帮助:在 FeatureId 属性上放置属性 [ForeignKey("Feature")]。

[ForeignKey("Feature")]
public int? FeatureId { get; set; }

public Feature Feature { get; set; }

这是其中的一部分。另一部分是我在另一侧有一个ICollection<Feature>。当我添加第二个引用时,它变得混乱了,所以我不得不在ICollection上添加一个InverseProperty。通过这两个修复措施,问题得到了解决。 - Doug
如上所述,您的命名约定是错误的。两个实体都应具有相同的“FeatureId”属性。在您的功能实体中仅使用“Id”不是良好的命名约定。首先,实体框架会查找实体中的[实体名称]Id属性,并自动将其映射为主键。然后,在其他实体中只需使用相同的名称以及“public virtual ICollection<Feature> Features {get;set;}”,EF将完成其余工作。 - Talon
1
Code First 还使用了没有 [实体名称] 前缀的 Id 约定,因此这样做没有任何问题。使用 "Id" 作为键字段是常见的、良好的实践和 Entity Framework 约定的一部分。 - Trevor de Koekkoek
关键在于 int? 允许为空。 - Rafael Fernandes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接