2012-09-16 43 views
1

Im新的Entity框架5和Im試圖支持枚舉,但我有一些問題。在使用EF5時,我使用了以前的版本,這是爲了創建數據庫並從數據庫生成模型並使用代碼生成。因此,我將模型的代碼生成屬性更改爲「default」,然後刪除.tt文件。EF5中的外部枚舉

我有多個DLL的解決方案,其中一個有DataModel(EDMX),另一個有一個名爲「EnumGender」的枚舉,它有2個值:男性和女性。

在db中,我有一個表有一個名爲「Gender」(smallint)的字段的用戶,並試圖爲它使用「EnumGender」。

EnumGender在名爲「Sample.Datatypes.Enums」的命名空間中,所以在edmx模型瀏覽器中試圖添加一個Enum。爲此,我設置了「EnumGender」作爲名稱,我沒有添加任何值,並且選中了「參考外部類型」複選框,並在文本框中輸入了「Sample.Datatypes.Enums.EnumGender」。

問題是,似乎EF正在數據模型命名空間中創建一個新的枚舉,我不想要,我想在「Sample.Datatypes.Enums」命名空間中使用EnumGender。另外,該EF創建新的枚舉沒有值...如果我進入到數據模型CS文件(生成的代碼),這是它添加了什麼:

/// <summary> 
/// No Metadata Documentation available. 
/// </summary> 
[EdmEnumTypeAttribute(NamespaceName="SampleModel", Name="EnumGender")] 
[DataContractAttribute()] 
public enum EnumGender : short 
{ 
} 

我有沒有發生什麼事的線索.. 。也許我不能使用外部dll的數據類型...但對於我所讀到的有關枚舉支持,我應該可以做到這一點...

我真的很感激,如果你能幫我解決這個問題。

謝謝! 胡安

回答

1

雖然不明顯,但這是設計。 EntityObject模板(將模型的代碼生成屬性設置爲「default」時使用的模板)不使用外部類型,因爲它需要類型具有特定屬性(EdmEnumTypeAttribute和DataContractAttribute用於枚舉)。如果類型本身也是由模板生成的,則只能可靠地滿足該約束。

我強烈建議使用DbContext模板(默認添加的.tt文件),因爲它使用POCO類型,因此支持外部類型。

但是,如果你的情況確實需要您使用EntityObject模板有辦法去改變它使用外部枚舉類型:

  1. 確保您的枚舉類型具有相同的屬性生成一個。 (是的,這意味着它不能與使用EnityObject生成的不同實體模型共享)
  2. 下載並安裝EF 5.x EntityObject T4模板:http://visualstudiogallery.msdn.microsoft.com/1da40393-b5ec-404a-a000-6a7e6e911339 如果您正在使用Web項目,請使用此一個相反:http://visualstudiogallery.msdn.microsoft.com/94b48556-fcf0-4b9b-8615-20f9066ae9ac
  3. 隨時隨地模型的實體設計視圖中單擊右鍵,選擇「添加代碼生成項...」
  4. 添加「EF 5.x的EntityObject生成器」
  5. 打開。已添加
  6. 搜索public string SourceCsdlPath{ get; set; }和加入這一行之前,TT文件:

    GetSourceSchemaTypes<EnumType>() 
        .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) 
        .OrderBy(c => c.Name) 
    

private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; 

7.搜索GetSourceSchemaTypes<EnumType>().OrderBy(c => c.Name),取而代之的是

8.搜索string typeName = MultiSchemaEscape(usage.EdmType, code); 並將其替換爲:

string typeName = code.Escape(usage.EdmType.MetadataProperties 
          .Where(p => p.Name == ExternalTypeNameAttributeName) 
          .Select(p => (string)p.Value) 
          .FirstOrDefault()) 
     ?? MultiSchemaEscape(usage.EdmType, code);