Get the primary key value of an arbitrary entity in code first

前端 未结 3 534
小鲜肉
小鲜肉 2020-12-09 18:02

Is there such a method?

object GetPrimaryKeyValue(DbEntityEntry entry);

Or how should it be implemented?

相关标签:
3条回答
  • 2020-12-09 18:27

    You don't need an attached T item. This may be long winded, but it works.

    public object[] GetPrimaryKeyValues<T>(DbContext databaseContext, T item)
    {
      return ((IObjectContextAdapter)databaseContext).ObjectContext.CreateEntityKey(typeof(T).Name.Pluralize(), item).EntityKeyValues.Select(kv => kv.Value).ToArray();
    }
    

    The return type is suitable to use in a Find, for example. See, the key values is actually an array of objects.

    If you need Pluralize(), here it is:

    using System;
    using System.Data.Entity.Design.PluralizationServices;
    using System.Linq;
    using System.Reflection;
    
    namespace Atlas.Core.Kernel.Extensions
    {
        public static class Strings
        {
          private static PluralizationService pluralizationService = PluralizationService.CreateService(System.Globalization.CultureInfo.CurrentUICulture);
          public static string Pluralize(this MemberInfo memberInfo)//types, propertyinfos, ect
          {
            return Pluralize(memberInfo.Name.StripEnd());
          }
    
          public static string Pluralize(this string name)
          {
            return pluralizationService.Pluralize(name); // remove EF type suffix, if any
          }
    
    
    
        }
      }
    
    0 讨论(0)
  • 2020-12-09 18:29

    I am also looking to find the Primary Key of an entity. I am using Generics in my repository so I don't know the Entity until runtime. The only way I have found to do this so far is with a sql statement.

    public abstract class GenericRepository<T> : ApiController,IGenericRepository<T> where T : class
    {
    
    
        string sqlstr = @"
            SELECT COLUMN_NAME
            FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
            WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + CONSTRAINT_NAME), 'IsPrimaryKey') = 1
            AND TABLE_NAME = '" + typeof(T).ToString() + "' AND TABLE_SCHEMA = 'dbo'";
    
        private Entities _entities = new Entities();
    
    
        public  virtual IQueryable<T> GetAll()
        {
            DbSqlQuery<T> queryTest = _entities.Set<T>().SqlQuery(sqlstr);
    

    This is just a pratial of the full class but hopefully shows the solution I am using.

    0 讨论(0)
  • 2020-12-09 18:44

    You need to cast your DbContext to IObjectContextAdapter so you can access the underlying ObjectContext which gives you access to some more advanced features hidden by DbContext.

    Inside your class which derives DbContext the following method will work.

    object GetPrimaryKeyValue(DbEntityEntry entry)
    {
        var objectStateEntry = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager.GetObjectStateEntry(entry.Entity);
        return objectStateEntry.EntityKey.EntityKeyValues[0].Value;
    }
    

    If there is more than one key then you should iterate over the EntityKeyValues property.

    0 讨论(0)
提交回复
热议问题