1

我是实体框架 5 的新手,我正在尝试枚举支持,但我遇到了一些问题。我使用 EF5,就像我使用以前的版本一样,这是创建数据库并从数据库生成模型并使用代码生成。因此,我将模型的代码生成属性更改为“默认”并删除了 .tt 文件。

我有一个包含多个 dll 的解决方案,其中一个有 DataModel (edmx),另一个有一个名为“EnumGender”的枚举,它有 2 个值:男性和女性。

在数据库中,我有一个表用户,其中有一个名为“性别”(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 的数据类型......但是对于我读到的关于枚举支持的内容,我应该能够做到这一点......

如果您能帮助我解决这个问题,我将不胜感激。

谢谢!胡安

4

1 回答 1

1

虽然不明显,但这是设计使然。EntityObject 模板(将模型的代码生成属性设置为“默认”时使用的模板)不使用外部类型,因为它要求类型具有某些属性(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. 打开添加的 .tt 文件
  6. 在它之前搜索public string SourceCsdlPath{ get; set; }并添加这一行:

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

7. 搜索GetSourceSchemaTypes<EnumType>().OrderBy(c => c.Name)并替换为:

GetSourceSchemaTypes<EnumType>()
    .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
    .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);
于 2012-09-18T20:01:11.663 回答