2011-08-31 9 views

risposta

24

È necessario trasmettere il numero DbContext a IObjectContextAdapter in modo da poter accedere al sottostante ObjectContext che consente di accedere ad alcune funzionalità più avanzate nascoste da DbContext.

All'interno della classe che deriva da DbContext, il seguente metodo funzionerà.

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

Se v'è più di una chiave allora si dovrebbe iterare la proprietà EntityKeyValues.

+4

che funziona solo se l'entità esiste nel 'ObjectStateManager'. C'è un modo per ottenere anche la chiave di entità di una voce distaccata? – Shimmy

+1

Sto avendo lo stesso problema. ogni volta che faccio riferimento a ObjectStateManager ottengo questo errore. ObjectStateManager non contiene ObjectStateEntry con un riferimento a un oggetto di tipo 'NAME_OF_ENTITY' – Hemslingo

+0

@Shimmy, vedere la mia risposta – toddmo

0

Sto anche cercando di trovare la chiave primaria di un'entità. Sto usando Generics nel mio repository quindi non conosco l'Entity fino al runtime. L'unico modo che ho trovato per fare questo finora è con una dichiarazione 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); 

Questo è solo un pratial della classe pieno, ma si spera mostra la soluzione che sto usando.

0

Non è necessario un allegato T item. Questo può essere a lungo, ma funziona.

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

Il tipo di ritorno è adatto da utilizzare in un Find, per esempio. Vedi, i valori chiave sono in realtà una serie di oggetti.

Se avete bisogno plurale(), qui è:

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 
     } 



    } 
    } 
Problemi correlati