2016-09-20 69 views
1

使用基于EF6的代码为什么Add-Migration突然生成非空代码迁移?

我的实际实体并未更改,但添加了新的DBSet以允许直接查询导航属性。

如果我运行添加迁移,它会生成一个非空迁移,只需对外键重新命名即可。

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

的DB模式:(我只显示相关的导航性能)。

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

public class ConfigurationClass 
{ 
    public int Id { get; set; } 

    public List<ConfigurationPropertyBase> ConfigurationProperties { get; set; } 
} 

public abstract class ConfigurationPropertyBase 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    //(no navigation propeties here) 
} 

我有一些来自ConfigurationPropertyBase继承的类,但他们只包含简单的属性,如int或字符串(没有导航性能),但其中之一是:

public class ConfigurationPropertyComplex : ConfigurationPropertyBase 
{ 
    public ConfigurationClass ConfigurationClass { get; set; } 
} 
+0

您还可以添加ConfigurationPropertyBase的代码吗?同样,考虑到名称中包含Base这个词,我会询问在您的模型中是否有派生类已经改变。 – strongbutgood

+0

我确实发现了一个变化。我编辑了这个问题。它不在模型类中,而是在DbContext中。但问题仍然存在。为什么会产生这样的迁移? – Eiver

+0

EF生成将关系存储在数据库中所需的列,然后在您使用POCO时在DbContext内部无声管理它们。因为您需要有一些方法来关联两个实体,所以EF将使用父级的PK来定义子实体上的隐式外键。我会更新我的答案以匹配。 – strongbutgood

回答

1

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

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

考虑到这一点,您可能没有更改模型你的思想,但可能在另一个类,你已经改变了一个隐式的外键的导航属性。还取决于您是否具有派生类ConfigurationPropertyBase,那么这些变化将影响模型。

在任何情况下,请按照建议明确定义您的外键属性,使生活变得如此简单。 也请更新您的问题,包括ConfigurationPropertyBase类和一个或两个其派生。

编辑响应更新问题

当你发现改变是在上下文本身。当您将ConfigurationClass添加到上下文时,必须重新排列其隐式外键。

再次引述documentation

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

接受建议并明确管理外键属性,以便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; } 
} 

是的,它是一大堆更多的工作和学习,但随后EF会做完全按照你说的。有关数据注释的更多documentation应该会对您有所帮助。

相关问题