Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get to the primary key of a self tracking entity?

I am trying to create a generic method that will retrieve an item by its id:

public T GetByID(int id)
{
    return (T) context.GetObjectByKey(
        new System.Data.EntityKey(context.DefaultContainerName + "." +
             context.CreateObjectSet<T>().EntitySet.Name, 
             "ProductID", id));
}

Basically I am able to infer the entity name from T, however I have no idea how to figure out what the primary key is for an entity?

like image 324
e36M3 Avatar asked Aug 10 '10 16:08

e36M3


People also ask

How do I set primary key in Entity Framework?

Configuring a primary key By convention, a property named Id or <type name>Id will be configured as the primary key of an entity. Owned entity types use different rules to define keys. You can configure a single property to be the primary key of an entity as follows: Data Annotations.

What is the EF core convention for primary keys?

EF Core will specify that the primary key column values are generated automatically by the database.

How is primary key defined in model class?

For defining the primary key, it provides HasKey() method. The Fluent API takes priority over the Data Annotation attributes. To specify the mappings using Code First Fluent API, we have to override the OnModelCreating() method. The OnModelCreating() method is called before the models are created.


1 Answers

I ended up creating my own attribute and modifying the T4 template to place that attribute above the primary key column. Here are the steps I took:

  1. Add the following above the [DataMember] attribute in the T4 template:

    <#if (ef.IsKey(edmProperty)) {#>    
    [PrimaryKeyAttribute]
    <#}#>
    
  2. Create the PrimaryKeyAttribute:

    [AttributeUsage(AttributeTargets.Property)]
    public class PrimaryKeyAttribute : Attribute
    {}
    
  3. Introduce a helper method to determine the primary key of an entity:

    private string GetPrimaryKey<K>()
    {
        string primaryKey = string.Empty;
    
        PropertyInfo[] entityProperties = typeof(K).GetProperties();
    
        foreach (PropertyInfo prop in entityProperties)
        {
            object[] attrs = prop.GetCustomAttributes(false);
            foreach (object obj in attrs)
            {
                if (obj.GetType() == typeof(PrimaryKeyAttribute))
                {
                    primaryKey = prop.Name;
                    break;
                }
            }
        }
    
        if (string.IsNullOrEmpty(primaryKey))
            throw new Exception("Cannot determine entity's primary key");
    
        return primaryKey;
    }
    
  4. Finally write the generic GetByID as such:

    public T GetByID(int id)
    {
        return (T)context.GetObjectByKey(new EntityKey(context.DefaultContainerName 
                                            + "." + context.CreateObjectSet<T>().EntitySet.Name
                                            , GetPrimaryKey<T>(), id));            
    }
    
like image 137
e36M3 Avatar answered Sep 29 '22 16:09

e36M3