Entity Frameworkコアでプライマリキー値を取得する方法

entity-framework entity-framework-core primary-key repository-pattern

質問

私たちは現在、抽象リポジトリのIObjectContextAdapterに依存する以下のメソッドを使用しています。私が読んでいるところでは、ObjectContextに関連するものがEntity Framework Coreから切り詰められているようです。以下のメソッドは、ObjectContextに関連するものに依存する唯一の場所です。

Entity Frameworkコアにアップグレードしたいと考えています。これが唯一のロードブロックです。 Entity Framework Core APIを使用してエンティティの主キーの値を取得する方法はありますか?

// Entity Framework
public virtual int GetKey(T entity)
{
    var oContext = ((IObjectContextAdapter)_DbContext).ObjectContext;
    var oSet = oContext.CreateObjectSet<T>();
    var keyName = oSet.EntitySet.ElementType
                                .KeyMembers
                                .Select(k => k.Name)
                                .Single();

    return (int)entity.GetType().GetProperty(keyName).GetValue(entity, null);
}

受け入れられた回答

私も同様の問題に直面し、以下の解決策を見出した

// Entity Framework Core
public virtual int GetKey<T>(T entity)
{
    var keyName = Context.Model.FindEntityType(typeof (T)).FindPrimaryKey().Properties
        .Select(x => x.Name).Single();

    return (int)entity.GetType().GetProperty(keyName).GetValue(entity, null);
}

人気のある回答

YuriyPの答えに基づいて、複合キー情報を得ることもできます:

 public static class Extensions {

    public static IEnumerable<string> FindPrimaryKeyNames<T>(this DbContext dbContext, T entity) {
      return from p in dbContext.FindPrimaryKeyProperties(entity) 
             select p.Name;
    }

    public static IEnumerable<object> FindPrimaryKeyValues<T>(this DbContext dbContext, T entity) {
      return from p in dbContext.FindPrimaryKeyProperties(entity) 
             select entity.GetPropertyValue(p.Name);
    }

    static IReadOnlyList<IProperty> FindPrimaryKeyProperties<T>(this DbContext dbContext, T entity) {
      return dbContext.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties;
    }

    static object GetPropertyValue<T>(this T entity, string name) {
      return entity.GetType().GetProperty(name).GetValue(entity, null);
    }

  }

そのようにして使用することができます:

var keyValues = context.FindPrimaryKeyValues(entity);    
var existingEntity = context.Set<TEntity>().Find(keyValues);


Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ