Reputation: 647
I have database with 80 tables (each table has got primary key). I have generated model in ASP.NET MVC project from database (Add - New Item - ADO.NET Entity Data Model). But in generated model I have 80 classes (for each table in database) without attribute [Key] 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 has no key defined. Define the key for this EntityType.
I often change database and then model in project so I can't each time add [Key] attribute to 80 AUTOGENERATED classes - what can I do??
Upvotes: 7
Views: 6154
Reputation: 17290
If your model contains any tables with multiple primary keys, you'll need to add the Column
annotation to your .tt file near line 66 as well, like this:
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)#>
<#
}
}
Upvotes: 8
Reputation: 412
To expand on @Kelly's answer, I too had to change the template and since the template is generated from another template, one would need to change the source. There is a source template for each of the supported languages but I suspect most people will be able to get by with changing the English templates which are denoted by the 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 needed in better context, this is what my Simple Properties section changed to:
var simpleProperties = typeMapper.GetSimpleProperties(entity);
if (simpleProperties.Any())
{
foreach (var edmProperty in simpleProperties)
{
if (ef.IsKey(edmProperty))
{
#>
[System.ComponentModel.DataAnnotations.Key]
<#
}
#>
<#=codeStringGenerator.Property(edmProperty)#>
<#
}
}
Upvotes: 5
Reputation: 985
I had same issue and solved it by adding the [Key] attributes into each class, but to avoid doing this manually, I modified the .tt file that is used to generate each of the classes. I added an if condition in the loop that loops through each simple property of the class. It adds the string "[Key]" before each primary key field. If you have a table with multiple fields making up the PK then you'd have to manually add the attributes for this ([Key, Column(Order = 0)]) or further work to update the .tt file (I was too lazy since I only have one table so far with a composite key). Once done, I saved the .tt file and it regenerated all of my classes and these errors went away.
foreach (var edmProperty in simpleProperties)
{
if (ef.IsKey(edmProperty)) {
#> [Key]
<# }
Upvotes: 12