web-dev-qa-db-ja.com

EntityFramework 6リフレクションを使用してIDフィールドを取得する方法は?

タイプパラメータTを持つジェネリックメソッドがあります。ここで、TはEFモデルのエンティティのタイプです。このタイプの識別フィールドの名前を取得する必要があります。私はこの記事を見ました: リフレクションなどでエンティティIDフィールドの名前を取得する方法はありますか? しかし、テビンが話しているときに何について話しているのか理解できませんEntitySetBaseおよびEntityTypeBaseタイプ。 EntityTypeBaseがモデル内のエンティティの1つのタイプである場合、EF6にはプロパティがありませんKeyMembers

16
Jonik

リフレクションだけで主キーを取得することはできないと思います。

まず、順序/優先度に関係なく、EFが主キーとなるプロパティを決定する方法を調べましょう。

主キーのEntityFrameworkの規則は次のとおりです。

  1. クラスは、名前が「ID」または「Id」であるプロパティを定義します
  2. または、クラス名の後に「ID」または「Id」が続く

GetPropertiesを使用して、プロパティ名を比較できます。

var key = type.GetProperties().FirstOrDefault(p => 
    p.Name.Equals("ID", StringComparison.OrdinalIgnoreCase) 
    || p.Name.Equals(type.Name + "ID", StringComparison.OrdinalIgnoreCase));

CustomAttributesを使用して、属性タイプを比較できます。

var key = type.GetProperties().FirstOrDefault(p => 
    p.CustomAttributes.Any(attr => attr.AttributeType == typeof(KeyAttribute)));

これは難しいことです。modelBuilderOnModelCreatingにカプセル化されており、modelBuilderをフィールド/プロパティとしてどこかに保存しても、キーを抽出することは依然として困難です。 HasKey関数から、すべてがカプセル化されます。 ソースコード を確認できます。そして、EFのすべては ObjectContext に依存し、ObjectContextが呼び出されると、たとえばこのコード行は、

((IObjectContextAdapter)context).ObjectContext

次に、データベースへの接続が確立されます。プロファイラーを使用して確認できます。そして、これがソースコードのコード抜粋です。

public override ObjectContext ObjectContext
{
    get
    {
        Initialize();
        return ObjectContextInUse;
    }
}

public void Initialize()
{
    InitializeContext();
    InitializeDatabase();
}

したがって、現在、主キーを取得する唯一の可能な方法は、-で説明されているように、オブジェクトセット、エンティティセット、キーメンバーなどを使用することです。 この投稿

var keyNames = set.EntitySet.ElementType.KeyMembers.Select(k => k.Name);
23
Yuliam Chandra