Как получить первичный ключ (ключи) в Entity Framework 4.1, то есть, используя DbContext - PullRequest
14 голосов
/ 02 августа 2011

Ответы, которые я вижу здесь, относятся к ObjectContext. Есть ли свойство для определения имен первичных ключей объекта при использовании DbContext?

Ах ... один из тех случаев, когда я хочу, чтобы Entity Framework был открытым исходным кодом! Я могу получить информацию об имени этого первичного ключа из метода .Find: -)

Ответы [ 5 ]

26 голосов
/ 02 августа 2011

Вы не можете использовать DbContext для этого - DbContext API - просто тупая оболочка с только самыми необходимыми функциями.Для всего более сложного вы должны преобразовать DbContext обратно в ObjectContext и использовать его.Попробуйте что-то вроде этого:

Извлечь имена ключей :

public static string[] GetEntityKeyNames<TEntity>(this DbContext context) where TEntity : class
{
  if (context == null)
    throw new ArgumentNullException("context");

  var set = ((IObjectContextAdapter)context).ObjectContext.CreateObjectSet<TEntity>();
  var entitySet = set.EntitySet;
  return entitySet.ElementType.KeyMembers.Select(k => k.Name).ToArray();
}

Вот метод, который извлечет значения ключа объекта:

public static IEnumerable<object> GetEntityKeys<TEntity>(this DbContext context, TEntity entity)
  where TEntity : class
{
  if (context == null)
    throw new NullReferenceException("context");

  var type = typeof(TEntity);

  var set = ((IObjectContextAdapter)context).ObjectContext.CreateObjectSet<TEntity>();
  var entitySet = set.EntitySet;
  var keys = entitySet.ElementType.KeyMembers;
  var props = keys.Select(k => type.GetProperty(k.Name));
  return props.Select(p => p.GetValue(entity));
}
4 голосов
/ 21 августа 2014

Решение , предложенное Ладиславом Мрнкой , не будет работать для производных объектов, так как Вы не можете создать набор объектов для производного типа .Вы увидите эту ошибку:

ArgumentException: для указанного типа сущности не определены EntitySets ... Если ... является производным типом, используйте базовый тип.Имя параметра: TEntity

Вот мое решение, позволяющее избежать создания набора объектов:

public string[] GetEntityKeyNames<TEntity>(DbContext context)
{
    if (context == null)
    {
        throw new ArgumentNullException("context");
    }
    var objectContext = ((IObjectContextAdapter)Context).ObjectContext;
    //We must use the namespace of the context and the type name of the entity
    string entityTypeName = context.GetType().Namespace + '.' + typeof(TEntity).Name;
    var entityType = objectContext.MetadataWorkspace.GetItem<EntityType>(entityTypeName, DataSpace.CSpace);
    return entityType.KeyProperties.Select(k => k.Name).ToArray();
}
1 голос
/ 11 мая 2014

Вот что я сделал, чтобы убедиться, что получил ключ.По сути, это то же самое, что и ответ @Agus Syahputra с одним важным отличием.Я добавил весь ответ ниже.

Примечание. Я проверял это только на EF6 и не уверен, работает ли это с более ранними версиями EF.

//I'm currently inside savechanges of my dbcontext
//if you're typing this code outside your dbcontext, replace this with your dbcontext    
var objectStateEntry = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager.GetObjectStateEntry(entry.Entity);
    string keyName = objectStateEntry.EntityKey.EntityKeyValues[0].Key;
1 голос
/ 29 мая 2012

Вы можете найти значение первичного ключа из класса EntityKey (http://msdn.microsoft.com/en-us/library/system.data.entitykey.aspx).

, и вы можете найти объект EntityKey из DbContext следующим образом:

ObjectContext context = ((IObjectContextAdapter)dbContext).ObjectContext;
EntityKey key = context.ObjectStateManager.GetObjectStateEntry(model).EntityKey;
1 голос
/ 02 августа 2011

вы можете получить ObjectContext, потому что DbContext в основном оборачивает ObjectContext ...

см
http://msdn.microsoft.com/en-us/library/gg696590%28v=vs.103%29.aspx
http://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext%28v=vs.103%29.aspx
http://msdn.microsoft.com/en-us/library/dd283139.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...