首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实体框架5不生成[Key]属性

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

Stack Overflow用户
提问于 2013-04-19 08:27:33
回答 3查看 3K关注 0票数 5

我将EF5与VS2012结合使用,当生成表时,我将面临一个问题。

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

  • Table1:人
  • 属性: Id (Guid)
  • 属性:名称(字符串)
  • Table2:角色
  • 属性: Id (Guid)
  • 属性:类型(字符串)
  • 属性: PersonId (Guid) (与表人关联)

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

  • 并发模式:无
  • 默认值:无
  • 实体键: True
  • Getter:公众
  • 姓名: Id
  • 可空:假
  • 策划人:公众
  • StoreGeneratedPattern:身份
  • 类型: Guid (我也尝试过使用Int32)

3)实体模型的属性是:

  • 代码生成策略:无
  • 数据库生成工作流: TablePerTypeStrategy (VS)
  • 数据库架构名称: dbo
  • DDL生成模板: SSDLToSQL10.tt (VS)
  • 实体容器访问:公共
  • 实体容器名称: DatabaseSchemaContainer
  • 启用延迟加载: True
  • 元数据伪影处理:嵌入到输出程序集中
  • 命名空间: DatabaseSchema
  • 多元新副词:假
  • 在Save: True上转换相关的文本模板
  • 更新属性方面:真
  • 在构建上验证: True

4)生成相关类,但不存在关键属性:

代码语言:javascript
复制
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)我创建了一个域服务来向客户端公开上述实体,如下所示:

代码语言:javascript
复制
[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标记的公共属性。

任何建议都是非常感谢的!

白酒

EN

回答 3

Stack Overflow用户

发布于 2013-12-03 06:54:20

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

代码语言:javascript
复制
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)));
}

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

代码语言:javascript
复制
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上单击右键并选择“运行自定义工具”。

票数 6
EN

Stack Overflow用户

发布于 2013-05-25 16:37:46

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

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

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

票数 1
EN

Stack Overflow用户

发布于 2013-05-25 18:54:57

vs2012不是正确的工具(目前?)要创建数据库模型,请执行以下操作。您可以更好地使用visio (而不是2013年!)或。您不需要它,数据建模的工作中有99%是创建正确的模型,而不是Vs2012尝试的模型,以自动化到c#的小步骤。

这就是为什么像您所需要的这样的明显特性没有包含在vs2012中。也许这是不可能的,因为vs2012是针对代码优先开发人员的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16100418

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档