Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework 5 does not generate [Key] attribute

I'm using EF5 with VS2012 and I'm facing a problem when the tables get generated.

1)I create an easy database schema (edmx) that contains 2 tables:

  • Table1: Person
  • Attribute: Id (Guid)
  • Attribute: Name (string)

  • Table2: Role

  • Attribute: Id (Guid)
  • Attribute: Type (string)
  • Attribute: PersonId (Guid) (association with the table Person)

2)defining the properties of the unique key (called Id) as:

  • Concurrency Mode: None
  • Default Value: None
  • Entity Key: True
  • Getter: Public
  • Name: Id
  • Nullable: False
  • Setter: Public
  • StoreGeneratedPattern: Identity
  • Type: Guid (I have also tried with Int32)

3)And the properties of the Entity model are:

  • Code Generation Strategy: None
  • Database Generation Workflow: TablePerTypeStrategy (VS)
  • Database Schema Name: dbo
  • DDL Generation Template: SSDLToSQL10.tt (VS)
  • Entity Container Access: Public
  • Entity Container Name: DatabaseSchemaContainer
  • Lazy Loading Enabled: True
  • Metadata Artifact Processing: Embed in Output Assembly
  • Namespace: DatabaseSchema
  • Pluralize New Objets: False
  • Transform Related Text Templates on Save: True
  • Update Property Facets: True
  • Validate On Build: True

4)the related classes are generated, but the [Key] attribute is not present:

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) I create a Domain service to expose the above entities to the client, like:

[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) Rebuilding and getting the error:

The Entity 'Person' in DomainService 'DomainService1' does not have a key defined. Entity types exposed by DomainService operations must have at least one public property marked with the KeyAttribute.

Any suggestion is appreciated!

Ale

like image 737
Alessandro Avatar asked Apr 19 '13 08:04

Alessandro


1 Answers

You may try to change code of the .tt generation template and add attributes to classes at time of generation. In your case you may change the method for properties generation like that:

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

and add namespace declaration to each generated class:

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)
        : "";
}

Once it done you can click right button on .tt and select "Run custom tool"

like image 98
Pavel Korsukov Avatar answered Oct 30 '22 21:10

Pavel Korsukov