【问题标题】:database first - EntityType xxx has no key defined. Define the key for this EntityType数据库优先 - EntityType xxx 没有定义键。定义此 EntityType 的键
【发布时间】:2013-08-03 17:50:57
【问题描述】:

我有 80 个表的数据库(每个表都有主键)。我已经从数据库中生成了 ASP.NET MVC 项目中的模型(添加 - 新项目 - ADO.NET 实体数据模型)。但是在生成的模型中,我有 80 个类(对于数据库中的每个表)没有属性 [Key],例如:

//------------------------------------------------------------------------------
// <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>
//------------------------------------------------------------------------------

namespace Blog.Models
{
    using System;
    using System.Collections.Generic;

    public partial class Comments
    {
        public int CommentId { get; set; }        
        public string Content { get; set; }
    }
}

所以我有错误: EntityType xxx 没有定义键。定义此 EntityType 的键。

我经常更改数据库然后在项目中建模,所以 我不能每次都将 [Key] 属性添加到 80 个自动生成的类 - 我该怎么办??

【问题讨论】:

  • 为什么在使用 DB-First 时需要 [Key] 属性?该属性仅适用于 Code-First。对于 DB-First,所有元数据都取自 edmx 文件。你删除了这个文件吗?您是否更改了连接字符串并从那里删除了 edmx 引用?
  • 在 edmx 文件中,我将 PK 设置为 Identity,但在 Model.tt 下自动生成的文件中,我在类中没有属性 [Key]。
  • 如前所述,预计模型没有 [Key] 属性。那么生成的上下文呢?它是否包含带有UnintentionalCodeFirstExceptionOnModelCreating 方法?
  • 是的,在自动生成的文件 Mode.Context.tt 我有方法:protected override void OnModelCreating(DbModelBuilder modelBuilder) { throw new UnintentionalCodeFirstException(); }
  • 您的 edmx 和模型是否在单独的类库项目中,如果是,您是否将连接字符串从库项目的 app.config 复制到 mvc Web 项目中的 web.config

标签: asp.net-mvc entity-framework


【解决方案1】:

我有同样的问题,并通过将 [Key] 属性添加到每个类中来解决它,但为了避免手动执行此操作,我修改了用于生成每个类的 .tt 文件。我在循环中添加了一个 if 条件,该条件循环遍历类的每个简单属性。它在每个主键字段之前添加字符串“[Key]”。如果您有一个包含多个字段组成 PK 的表,那么您必须手动添加此属性 ([Key, Column(Order = 0)]) 或进一步工作以更新 .tt 文件(我太懒了因为到目前为止我只有一个带有复合键的表)。完成后,我保存了 .tt 文件,它重新生成了我的所有类,这些错误就消失了。

foreach (var edmProperty in simpleProperties)
{
        if (ef.IsKey(edmProperty)) { 
#>           [Key]
<#      } 

【讨论】:

  • 这对我有用,尽管我必须使用其命名空间完全限定 Key。接下来,了解如何重新生成 EDMX 文件并自动包含此属性。
【解决方案2】:

如果您的模型包含任何具有多个主键的表,您还需要在 .tt 文件的第 66 行附近添加 Column 注释,如下所示:

var simpleProperties = typeMapper.GetSimpleProperties(entity);
if (simpleProperties.Any())
{
    var keyIndex = 0; // This is a new line
    foreach (var edmProperty in simpleProperties)
    {
        // The following if block is new
        if (ef.IsKey(edmProperty)) 
        {
#>          [System.ComponentModel.DataAnnotations.Key]
            [System.ComponentModel.DataAnnotations.Schema.Column(Order = <#=keyIndex.ToString()#>)]
<#
            keyIndex++;
#>
<#      }
#>
        <#=codeStringGenerator.Property(edmProperty)#>
<#
    }
}

【讨论】:

    【解决方案3】:

    要扩展@Kelly 的答案,我也必须更改模板,并且由于模板是从另一个模板生成的,因此需要更改源。每种支持的语言都有一个源模板,但我怀疑大多数人都可以通过更改由 LCID 1033 表示的英文模板来解决问题。

    我找到的文件是:

    C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ItemTemplates\CSharp\Data\1033\DbCtxCSEF6\CSharpDbContext.Types.tt                                                                                                                               
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ItemTemplates\Web\CSharp\1033\DbCtxCSWSEF6\CSharpDbContext.Types.tt                                                                                                                              
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ItemTemplatesCache\CSharp\Data\1033\DbCtxCSEF6\CSharpDbContext.Types.tt                                                                                                                          
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ItemTemplatesCache\Web\CSharp\1033\DbCtxCSWSEF6\CSharpDbContext.Types.tt                                                                                                                         
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\VWDExpress\ItemTemplates\CSharp\Data\1033\DbCtxCSEF6\CSharpDbContext.Types.tt                                                                                                                    
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\VWDExpress\ItemTemplates\Web\CSharp\1033\DbCtxCSWSEF6\CSharpDbContext.Types.tt                                                                                                                   
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\WDExpress\ItemTemplates\CSharp\Data\1033\DbCtxCSEF6\CSharpDbContext.Types.tt                                                                                                                     
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\WDExpress\ItemTemplates\Web\CSharp\1033\DbCtxCSWSEF6\CSharpDbContext.Types.tt
    

    为了将代码 sn-p 放在更好的上下文中,这就是我的简单属性部分更改为:

        var simpleProperties = typeMapper.GetSimpleProperties(entity);
        if (simpleProperties.Any())
        {
            foreach (var edmProperty in simpleProperties)
            {
                if (ef.IsKey(edmProperty)) 
                { 
    #>
        [System.ComponentModel.DataAnnotations.Key]
    <#
    
                }
    #>
        <#=codeStringGenerator.Property(edmProperty)#>
    <#
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-02
      • 2016-03-16
      • 2013-08-04
      • 2012-12-10
      • 2016-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多