5

我将 EF5 与 VS2012 一起使用,并且在生成表时遇到了问题。

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

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

  • 表 2:角色

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

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

  • 并发模式:无
  • 默认值:无
  • 实体键:真
  • 吸气剂:公共
  • 姓名:身份证
  • 可空:假
  • 二传手:公开
  • StoreGeneratedPattern:身份
  • 类型:Guid(我也尝试过 Int32)

3)Entity模型的属性是:

  • 代码生成策略:无
  • 数据库生成工作流程:TablePerTypeStrategy (VS)
  • 数据库模式名称:dbo
  • DDL 生成模板:SSDLToSQL10.tt (VS)
  • 实体容器访问:公共
  • 实体容器名称:DatabaseSchemaContainer
  • 延迟加载启用:真
  • 元数据工件处理:嵌入输出程序集
  • 命名空间:DatabaseSchema
  • 复数新对象:错误
  • 保存时转换相关文本模板: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 的公共属性。

任何建议表示赞赏!

啤酒

4

3 回答 3

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 上的右键并选择“运行自定义工具”

于 2013-12-03T06:54:20.670 回答
1

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

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

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

于 2013-05-25T16:37:46.183 回答
0

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

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

于 2013-05-25T18:54:57.120 回答