First the database - EntityType xxx does not have a specific key. Define a key for this EntityType

I have a database with 80 tables (each table has a primary key). I created a model in an ASP.NET MVC project from a database (Add - New Item - ADO.NET Entity Data Model). But in the generated model, I have 80 classes (for each table in the database) without the [Key] attribute, for example:

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

So, I have errors: EntityType xxx does not have a specific key. Define a key for this EntityType.

I often change the database and then model in the project, so I can’t add the [Key] attribute to 80 AUTOGENERATED classes every time - what can I do?

+6
source share
3 answers

I had the same problem and solved it by adding [Key] attributes to each class, but to avoid this manually, I changed the .tt file that is used to generate each of the classes. I added an if condition in the loop that intersects every simple property of the class. It adds the string [Key] in front of each primary key field. If you have a table with several fields that make up PK, you will have to manually add the attributes for this ([Key, Column (Order = 0)]) or continue working on updating the .tt file (I was too lazy since I only have one table with a composite key). After that I saved the .tt file and it restored all my classes and these errors disappeared.

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

If your model contains tables with several primary keys, you need to add the Column annotation to your .tt file next to line 66, for example:

 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)#> <# } } 
+8
source

To extend the answer to @Kelly, I also had to change the template, and since the template is created from another template, I need to change the source. There is a source template for each of the supported languages, but I suspect that most people will be able to cope with changing the English templates indicated by LCID 1033.

The files I found were:

 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 

And to put the code snippet in a more appropriate context, this is what my "Simple Properties" section changed:

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

Source: https://habr.com/ru/post/950971/


All Articles