EntityFramework 6如何使用反射获取identity-field?

时间:2014-08-05 14:54:40

标签: c# entity-framework reflection entity-framework-6

我有一个带参数T的泛型方法,其中T是EF模型中的实体类型。 我需要获得此类型的识别字段的名称。 我看到这篇文章:Is there a way to get entity id-field's name by reflection or whatever? 但我无法理解Tevin谈论 EntitySetBase EntityTypeBase 类型时所说的内容。 如果 EntityTypeBase 是模型中某个实体的类型,那么EF6没有属性 KeyMembers

1 个答案:

答案 0 :(得分:20)

我认为只有通过反思才能获得主键。

首先,让我们看看EF如何确定哪些属性(无论顺序/优先级是哪个)

  

主键的实体框架约定是:

     
      
  1. 您的班级定义了名称为“ID”或“Id”
  2. 的媒体资源   
  3. 或类名后跟“ID”或“Id”
  4.   

我们可以使用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)));

这是很难做到的,modelBuilder封装在OnModelCreating中,即使我们将modelBuilder保存在某个字段/属性中,仍然难以提取密钥从HasKey函数,一切都被封装。您可以查看source code。 EF中的所有内容都取决于ObjectContext,并且一旦ObjectContext被调用,例如这行代码,

((IObjectContextAdapter)context).ObjectContext

然后将建立与数据库的连接,您可以使用profiler进行检查。这是源代码的代码摘录。

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

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

因此,目前获取主键的唯一可能方法是通过对象集,实体集,关键成员等,如this post中所述

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