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

时间:2013-04-19 08:27:34

标签: entity-framework visual-studio-2012 entity-framework-5

我在VS2012中使用EF5,并且在生成表时我遇到了问题。

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

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

  • 表2:角色

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

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

  • 并发模式:无
  • 默认值:无
  • 实体键:True
  • Getter:Public
  • 姓名:Id
  • Nullable:False
  • Setter:Public
  • StoreGeneratedPattern:Identity
  • 类型:Guid(我也尝试使用Int32)

3)实体模型的属性是:

  • 代码生成策略:无
  • 数据库生成工作流程:TablePerTypeStrategy(VS)
  • 数据库架构名称:dbo
  • DDL生成模板:SSDLToSQL10.tt(VS)
  • 实体容器访问:公开
  • 实体容器名称:DatabaseSchemaContainer
  • 启用延迟加载:True
  • 元数据工件处理:嵌入输出程序集
  • 命名空间:DatabaseSchema
  • Pluralize New Objets:False
  • 保存时转换相关文本模板:True
  • 更新Property Facets:True
  • 在构建时验证: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; }
}

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)
    {

    }
}

6)重建并收到错误:

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

任何建议都表示赞赏!

啤酒

3 个答案:

答案 0 :(得分: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)));
}

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

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)
        : "";
}

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

答案 1 :(得分:1)

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

  

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

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

答案 2 :(得分:0)

vs2012不是创建数据库模型的正确工具(还是?)。 您可以更好地使用visio(不是2013!)或SQL Server Management Studio。 而且你不需要它,99%的数据建模工作正在创建正确的模型,而不是Vs2012尝试的,以自动化c#的小步骤。

这就是你需要的明显功能不包含在vs2012中的原因。也许它永远不可能,因为vs2012是针对代码优先的开发人员。

相关问题