2011-08-31 12 views

Respuesta

24

, es necesario especificar su DbContext a IObjectContextAdapter para que pueda acceder al ObjectContext subyacente que le da acceso a algunas funciones más avanzadas ocultas por DbContext.

Dentro de su clase, que deriva DbContext, funcionará el siguiente método.

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

Si hay más de una clave, entonces usted debe iterar sobre la propiedad EntityKeyValues.

+4

Eso sólo funciona si existe la entidad en el 'ObjectStateManager'. ¿Hay alguna manera de obtener la clave de entidad de una entrada separada también? – Shimmy

+1

Estoy teniendo el mismo problema. cada vez que hago referencia al ObjectStateManager, obtengo este error. El ObjectStateManager no contiene un ObjectStateEntry con una referencia a un objeto de tipo 'NAME_OF_ENTITY' – Hemslingo

+0

@Shimmy, ver mi respuesta – toddmo

0

También estoy buscando la clave principal de una entidad. Estoy usando Genéricos en mi repositorio, así que no conozco la Entidad hasta el tiempo de ejecución. La única forma que he encontrado para hacer esto hasta ahora es con una declaración sql.

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

Esto es sólo una pratial de la clase completa, pero esperemos que muestra la solución que estoy utilizando.

0

No necesita un T item adjunto. Esto puede ser largo aliento, pero funciona.

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

El tipo de retorno es adecuado para utilizar en un Find, por ejemplo. Ver, los valores clave son en realidad una matriz de objetos.

Si necesita pluralizar(), aquí está:

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 
     } 



    } 
    } 
Cuestiones relacionadas