我有一个带有类型参数 T 的泛型方法,其中 T 是 EF 模型中的实体类型。 我需要获得这种类型的标识字段的名称。 我看到这篇文章:Is there a way to get entity id-field's name by reflection or whatever? 但我不明白,Tevin 在谈论 EntitySetBase 和 EntityTypeBase 类型时在谈论什么。 如果 EntityTypeBase 是模型中实体之一的类型,那么 EF6 没有属性 KeyMembers。
最佳答案
我认为仅通过反射获取主键是不可能的。
首先,让我们看看 EF 如何确定哪些属性将成为主键,而不考虑顺序/优先级
- 作者 Convention
The Entity Framework convention for primary keys is:
- Your class defines a property whose name is “ID” or “Id”
- or a class name followed by “ID” or “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)));
- 作者 Fluent Api
这是很难做到的,modelBuilder
被封装在 OnModelCreating
中,即使我们将 modelBuilder
保存在某个地方作为字段/属性,仍然很难从 HasKey
函数中提取 key ,一切都被封装了。您可以查看 source code . EF 中的所有内容都取决于 ObjectContext
一旦 ObjectContext
被调用,例如这行代码,
((IObjectContextAdapter)context).ObjectContext
然后将建立与数据库的连接,您可以使用分析器进行检查。这是源代码的代码摘录。
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);
关于c# - EntityFramework 6 如何通过反射获取身份字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25141955/