C# 为什么添加迁移会突然生成非空代码迁移?

C# 为什么添加迁移会突然生成非空代码迁移?,c#,entity-framework,entity-framework-6,C#,Entity Framework,Entity Framework 6,使用基于代码的EF6 我的实际实体尚未更改,但添加了一个新的数据库集,以允许直接查询导航属性 如果我运行addmigration,它将生成一个非空的迁移,只为外键重命名一个奇怪的列 public override void Up() { RenameColumn(table: "dbo.ConfigurationPropertyBases", name: "ConfigurationClass_Id", newName: "ConfigurationClass_Id1"); Re

使用基于代码的EF6

我的实际实体尚未更改,但添加了一个新的数据库集,以允许直接查询导航属性

如果我运行addmigration,它将生成一个非空的迁移,只为外键重命名一个奇怪的列

public override void Up()
{
    RenameColumn(table: "dbo.ConfigurationPropertyBases", name: "ConfigurationClass_Id", newName: "ConfigurationClass_Id1");
    RenameIndex(table: "dbo.ConfigurationPropertyBases", name: "IX_ConfigurationClass_Id", newName: "IX_ConfigurationClass_Id1");
}
为什么会产生这样的迁移

DbContext中的更改:

public class ConfigurationContext : DbContext
{
   //(...)

    public DbSet<ConfigurationPackage> Packages { get; set; }
    public DbSet<ConfigurationPropertyBase> ConfigurationPropertyBases { get; set; }

    // THIS WAS ADDED
    public DbSet<ConfigurationClass> ConfigurationClass { get; set; }
}

实体框架约定将创建一列来保存模型中未明确定义的关系信息。 msdn中指出:

除了导航属性外,我们建议您在表示依赖对象的类型上包括外键属性。与主主键属性具有相同数据类型且名称遵循以下格式之一的任何属性都表示关系的外键

考虑到这一点,您可能没有在脑海中更改模型,但在另一个类中,您可能已使用隐式外键更改了导航属性。还取决于您是否拥有
ConfigurationPropertyBase
的派生类,这些派生类中的更改将影响模型

在任何情况下,按照建议显式定义外键属性,生活就会变得简单得多。 另外,请更新您的问题,以包括
ConfigurationPropertyBase
类及其一个或两个派生类

编辑以回答更新的问题

正如您所发现的,更改是在上下文本身中进行的。将
ConfigurationClass
添加到上下文时,它必须重新排列其隐式外键

再次引用:

当外键列不包括在模型中时,关联信息将作为独立对象进行管理。通过对象引用而不是外键属性跟踪关系。这种类型的关联称为独立关联。修改独立关联最常用的方法是修改为参与关联的每个实体生成的导航属性

接受建议并显式管理外键属性,这样EF就不会决定似乎没有意义的更改。 例如:

public class ConfigurationPackage
{
    public int Id { get; set; }
    //(...)
    [InverseProperty("ConfigurationPackage")]
    public List<ConfigurationClass> Configurations { get; set; }
}

public class ConfigurationClass
{
    public int Id { get; set; }
    [ForeignKey("ConfigurationPackage")]
    public int ConfigurationPackageId { get; set; }
    public ConfigurationPackage ConfigurationPackage { get; set; }
    [InverseProperty("ConfigurationClass")]
    public List<ConfigurationPropertyBase> ConfigurationProperties { get; set; }
}

public abstract class ConfigurationPropertyBase
{
    public int Id { get; set; }
    public string Name { get; set; }
    //(no navigation propeties here)
    [ForeignKey("ConfigurationClass")]
    public int ConfigurationClassId { get; set; }
    public ConfigurationClass ConfigurationClass { get; set; }
}
公共类配置包
{
公共int Id{get;set;}
//(...)
[反向属性(“配置包”)]
公共列表配置{get;set;}
}
公共类配置类
{
公共int Id{get;set;}
[外键(“配置包”)]
公共int-ConfigurationPackageId{get;set;}
公共配置包配置包{get;set;}
[反向属性(“配置类”)]
公共列表配置属性{get;set;}
}
公共抽象类配置PropertyBase
{
公共int Id{get;set;}
公共字符串名称{get;set;}
//(此处无导航属性)
[外键(“配置类”)]
公共int-ConfigurationClassId{get;set;}
公共配置类配置类{get;set;}
}

是的,这是一个更大的工作和更多的学习,但届时英孚将完全按照你说的。关于数据注释的更多信息应该会让您感觉正确。

您是否也可以为ConfigurationPropertyBase添加代码。同时给出了这个名字,包括词库,我想问一下在你的模型中是否有这样的派生类已经改变了。我编辑了这个问题。它不在模型类中,而是在DbContext中。但问题仍然存在。为什么它会生成这样的迁移?EF生成在数据库中存储关系所需的列,然后在使用POCO时在DbContext中对它们进行静默管理。因为您需要某种方式来关联这两个实体,EF将使用父实体的PK在子实体上定义隐式外键。我将更新我的答案以匹配。
public class ConfigurationPropertyComplex : ConfigurationPropertyBase
{
    public ConfigurationClass ConfigurationClass { get; set; }
}
public class ConfigurationPackage
{
    public int Id { get; set; }
    //(...)
    [InverseProperty("ConfigurationPackage")]
    public List<ConfigurationClass> Configurations { get; set; }
}

public class ConfigurationClass
{
    public int Id { get; set; }
    [ForeignKey("ConfigurationPackage")]
    public int ConfigurationPackageId { get; set; }
    public ConfigurationPackage ConfigurationPackage { get; set; }
    [InverseProperty("ConfigurationClass")]
    public List<ConfigurationPropertyBase> ConfigurationProperties { get; set; }
}

public abstract class ConfigurationPropertyBase
{
    public int Id { get; set; }
    public string Name { get; set; }
    //(no navigation propeties here)
    [ForeignKey("ConfigurationClass")]
    public int ConfigurationClassId { get; set; }
    public ConfigurationClass ConfigurationClass { get; set; }
}