实体框架4.1数据库优先不向DbContext T4生成的类添加主键 [英] Entity Framework 4.1 Database First does not add a primary key to the DbContext T4 generated class

本文介绍了实体框架4.1数据库优先不向DbContext T4生成的类添加主键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始使用Entity Framework 4.1,尝试了数据库优先"模式.当EF使用"ADO.Net DbContext Generator"生成Model类时,它是否不应该使用[Key]属性来标识该类的主键?没有这个,它似乎与T4 MVCS脚手架不兼容.

I am just getting started with Entity Framework 4.1, trying out the "database first" mode. When EF generates a Model class with the "ADO.Net DbContext Generator," shouldn't it identify the primary key for the class with a [Key] attribute? Without this, it appears incompatible with the T4 MVCScaffolding.

以下是详细信息:

使用实体数据模型设计器GUI,我从现有数据库中向模型添加了一个简单的国家"表. GUI正确地将名为"PK"的单个整数身份密钥字段标识为我的主键. (A!我是新用户,所以我无法添加屏幕截图.我在下面包括了CSDL.)但是,当EF使用"ADO.Net DbContext Generator"生成代码时,它无法识别PK字段作为生成的类中的关键字段(请参见下面的代码摘录).

Using the Entity Data Model Designer GUI, I have added a simple "country" table to the model from my existing database. The GUI correctly identifies a single integer identity key field named "PK" as my primary key. (Alas! I'm a new user so I can't add a screenshot. I've included the CSDL instead below.) However, when EF generates code using the "ADO.Net DbContext Generator", it does not identify the PK field as the key field in the generated class (see code excerpt below).

国家/地区"表的CSDL:

The CSDL for the "country" table:

<edmx:ConceptualModels>
  <Schema Namespace="EpiDataModel" Alias="Self" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
    <EntityContainer Name="EpiModelEntities" annotation:LazyLoadingEnabled="true">
      <EntitySet Name="countries" EntityType="EpiDataModel.country" />
    </EntityContainer>
    <EntityType Name="country">
      <Key>
        <PropertyRef Name="PK" />
      </Key>
      <Property Name="PK" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
      <Property Name="Abbreviation" Type="String" Nullable="false" MaxLength="200" Unicode="false" FixedLength="false" />
      <Property Name="Name" Type="String" MaxLength="1024" Unicode="false" FixedLength="false" />
      <Property Name="Description" Type="String" MaxLength="1024" Unicode="false" FixedLength="false" />
      <Property Name="Sequence" Type="Int32" />
    </EntityType>
  </Schema>
</edmx:ConceptualModels>

这是自动生成的代码:

//------------------------------------------------------------------------------
// <auto-generated>
//    This code was generated from a template.
//
//    Manual changes to this file may cause unexpected behavior in your application.
//    Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;

namespace MvcApplication1.Areas.Epi.Models
{
    public partial class country
    {
        public int PK { get; set; }
        public string Abbreviation { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public Nullable<int> Sequence { get; set; }
    }
}

当我尝试使用MVCScaffolding T4模板来搭建控制器时,这会导致问题.我收到一个错误没有属性似乎是主键". NuGet软件包管理器控制台的命令和输出如下:

This causes a problem when I try to scaffold a controller using the MVCScaffolding T4 template. I get an error "No properties appear to be primary keys." The command and output from the NuGet Package Manager Console is below:

PM> scaffold controller MvcApplication1.Areas.Epi.Models.country -Area Epi -NoChildItems -DbContextType MvcApplication1.Areas.Epi.Models.EpiModelEntities -Force
Scaffolding countriesController...
Get-PrimaryKey : Cannot find primary key property for type 'MvcApplication1.Areas.Epi.Models.country'. No properties appear to be primary keys.
At C:\work\EPI\EPIC_MVC3\sandbox\MvcApplication1\packages\MvcScaffolding.1.0.6\tools\Controller\MvcScaffolding.Controller.ps1:74 char:29
+ $primaryKey = Get-PrimaryKey <<<<  $foundModelType.FullName -Project $Project -ErrorIfNotFound
    + CategoryInfo          : NotSpecified: (:) [Get-PrimaryKey], Exception
    + FullyQualifiedErrorId : T4Scaffolding.Cmdlets.GetPrimaryKeyCmdlet

但是,如果我手动更改生成的类以向字段添加[Key]属性,则上面显示的完全相同的脚手架命令可以正常工作:

However, if I manually change the generated class to add a [Key] attribute to the field, then the exact same scaffolding command shown above works fine:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; // manually added

namespace MvcApplication1.Areas.Epi.Models
{
    public partial class country
    {
        [Key]                        // manually added
        public int PK { get; set; }
        public string Abbreviation { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public Nullable<int> Sequence { get; set; }
    }
}

那么EF Database First和T4 MVCScaffolding为什么不能一起玩?即使没有脚手架问题,EF类也不需要知道什么是关键字段吗?

So why aren't EF Database First and the T4 MVCScaffolding playing nice together? And even without the scaffolding issue, don't the EF classes need to know what the key field(s) are?

推荐答案

T4模板不使用数据注释,因为从模板生成的类不需要它们. EF也不需要它们,因为映射是在XML文件中定义的,而不是在代码中定义的.如果您需要数据注释,则必须:

T4 Templates doesn't use data annotations because classes generated from templates don't need them. EF also don't need them because mapping is defined in XML files not in code. If you need data annotations you must either:

  • 修改T4模板以使用它们(这需要了解EF元数据模型)
  • 不要使用模板,而是先使用代码
  • 使用伙伴类手动添加数据注释,并希望脚手架能够识别它们
  • Modify T4 template to use them (this requires understanding of EF metadata model)
  • Don't use templates and use code first instead
  • Use buddy classes to manually add data annotations and hope that scaffolding will recognize them

这篇关于实体框架4.1数据库优先不向DbContext T4生成的类添加主键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆