2016-09-20 38 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應該會對您有所幫助。

相關問題