实体框架5不生成[Key]属性

Ale*_*dro 5 entity-framework entity-framework-5 visual-studio-2012

我在VS2012上使用EF5,当表生成时我遇到了问题.

1)我创建了一个包含2个表的简单数据库模式(edmx):

  • 表1:人
  • 属性:Id(Guid)
  • 属性:名称(字符串)

  • 表2:角色

  • 属性:Id(Guid)
  • 属性:类型(字符串)
  • 属性:PersonId(Guid)(与表Person关联)

2)将唯一键的属性(称为Id)定义为:

  • 并发模式:无
  • 默认值:无
  • 实体密钥:真实
  • Getter:公开
  • 姓名:Id
  • 可空:错误
  • 塞特:公众
  • StoreGeneratedPattern:Identity
  • 类型:Guid(我也试过Int32)

3)实体模型的属性是:

  • 代码生成策略:无
  • 数据库生成工作流:TablePerTypeStrategy(VS)
  • 数据库架构名称:dbo
  • DDL生成模板:SSDLToSQL10.tt(VS)
  • 实体容器访问:公共
  • 实体容器名称:DatabaseSchemaContainer
  • 延迟加载已启用:正确
  • 元数据工件处理:嵌入输出程序集
  • 命名空间:DatabaseSchema
  • 多元化的新目标:错误
  • 保存时转换相关文本模板:True
  • 更新Property Facets:True
  • 在Build上验证:True

4)生成相关的类,但不存在[Key]属性:

using System;
using System.Collections.Generic;

public partial class Person
{
    public Person()
    {
        this.Role = new HashSet<Role>();
    }

    //[Key] <-- Missed!
    public System.Guid Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Role> Role { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

5)我创建一个域服务,将上述实体暴露给客户端,如:

[EnableClientAccess]
public class DomainService1 : DomainService
{
    [Query]
    public IEnumerable<Person> GetPersonSet()
    {

    }

    [Update]
    public void UpdatePerson(Person person)
    {

    }

    [Insert]
    public void InsertPerson(Person person)
    {

    }

    [Delete]
    public void DeletePerson(Person person)
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

6)重建并得到错误:

DomainService"DomainService1"中的实体"Person"没有定义密钥.DomainService操作公开的实体类型必须至少有一个用KeyAttribute标记的公共属性.

任何建议表示赞赏!

麦酒

Pav*_*kov 6

您可以尝试更改.tt生成模板的代码,并在生成时向类添加属性.在您的情况下,您可以更改属性生成方法,如下所示:

public string Property(EdmProperty edmProperty)
{
    return string.Format(
        CultureInfo.InvariantCulture,

        //Custom check for key field
        (_ef.IsKey(edmProperty) ? "[Key]" : "") +

        "{0} {1} {2} {{ {3}get; {4}set; }}",
        Accessibility.ForProperty(edmProperty),
        _typeMapper.GetTypeName(edmProperty.TypeUsage),
        _code.Escape(edmProperty),
        _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
        _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
Run Code Online (Sandbox Code Playgroud)

并为每个生成的类添加名称空间声明:

public string UsingDirectives(bool inHeader, bool includeCollections = true)
{
    return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
        ? string.Format(
            CultureInfo.InvariantCulture,

            //Namespace for KeyAttribute goes here
            "{0}using System; using System.ComponentModel.DataAnnotations;{1}" +
            "{2}",
            inHeader ? Environment.NewLine : "",
            includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
            inHeader ? "" : Environment.NewLine)
        : "";
}
Run Code Online (Sandbox Code Playgroud)

完成后,您可以单击.tt上的右键并选择"运行自定义工具"


Ric*_*ard 1

虽然这个答案最初来自 EF4,但我怀疑情况仍然如此:

T4 模板不使用数据注释,因为从模板生成的类不需要它们。(来源

我怀疑这也可能与以下事实有关:首先在代码中您不需要 KeyAttribute,除非您使用不遵循约定的关键字段(例如,Id 和 PersonId 自动用作 Person 实体上的键)。如果您在模型优先路线上走得不太远,也许可以考虑使用代码优先?