问题描述
我有一个带有类型参数 T 的泛型方法,其中 T 是 EF 模型中的实体类型.我需要获取此类型中标识字段的名称.我看到了这篇文章:有没有办法通过反射或其他方式获取实体 id-field 的名称?但是我不明白 Tevin 在谈到 EntitySetBase 和 EntityTypeBase 类型时在说什么.如果 EntityTypeBase 是模型中实体之一的类型,则 EF6 没有属性 KeyMembers.
I have a generic method with type parameter T, where T is the type of entity in EF model. I need to get the name of identifying field in this type. I saw this article: Is there a way to get entity id-field's name by reflection or whatever? But I can't understand, what Tevin talking about when he talks about EntitySetBase and EntityTypeBase types. If EntityTypeBase is type of one of the entities in model, so then EF6 have no property KeyMembers.
推荐答案
我觉得只靠反射是不可能得到主键的.
I don't think it's possible to get the primary keys only by reflection.
首先,让我们看看 EF 如何确定哪些属性将成为主键,而不管顺序/优先级如何
First, let's find out how EF determine which property(ies) that will be primary key(s) regardless of the order / priority
- 由 公约
主键的实体框架约定是:
The Entity Framework convention for primary keys is:
- 您的类定义了一个名为ID"或Id"的属性
- 或类名后跟ID"或Id"
我们可以使用GetProperties
来比较属性名.
We can use GetProperties
and compare the property name.
var key = type.GetProperties().FirstOrDefault(p =>
p.Name.Equals("ID", StringComparison.OrdinalIgnoreCase)
|| p.Name.Equals(type.Name + "ID", StringComparison.OrdinalIgnoreCase));
- 由
[KeyAttribute]
我们可以使用CustomAttributes
并比较属性类型.
We can use CustomAttributes
and compare the attribute type.
var key = type.GetProperties().FirstOrDefault(p =>
p.CustomAttributes.Any(attr => attr.AttributeType == typeof(KeyAttribute)));
- 由 Fluent Api
这是一个很难做到的, modelBuilder
被封装在 OnModelCreating
中,即使我们将 modelBuilder
保存为 field/属性,从HasKey
函数中提取key还是很困难的,一切都被封装了.您可以查看源代码.EF 中的所有内容都取决于 ObjectContext
并且一旦 ObjectContext
被调用,例如这行代码,
This is the one that's difficult to do, modelBuilder
is encapsulated in the OnModelCreating
and even if we save the modelBuilder
somewhere as field/property, it's still difficult to extract the key from HasKey
function, everything is encapsulated. You can check the source code. And everything in EF depends on ObjectContext
and once the ObjectContext
is called, for example this line of code,
((IObjectContextAdapter)context).ObjectContext
然后将建立与数据库的连接,您可以使用分析器进行检查.这是源代码的代码摘录.
then a connection to the database will be made, you can check using profiler. And here is the code excerpt of the source code.
public override ObjectContext ObjectContext
{
get
{
Initialize();
return ObjectContextInUse;
}
}
public void Initialize()
{
InitializeContext();
InitializeDatabase();
}
因此,目前获取主键的唯一可能方法是通过对象集、实体集、键成员等,如 这篇文章
Therefore, currently the only possible way to get the primary key(s) is through object set, entity set, key members, etc as explained in this post
var keyNames = set.EntitySet.ElementType.KeyMembers.Select(k => k.Name);
这篇关于EntityFramework 6 如何通过反射获得身份字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!