У меня есть общий метод с параметром типа T, где T - тип объекта в EF-модели. Мне нужно получить имя поля идентификации в этом типе. Я видел эту статью: Есть ли способ получить имя идентификатора объекта с помощью отражения или что-то еще? Но я не могу понять, о чем говорит Тевин, когда он говорит о типах EntitySetBase и EntityTypeBase. Если EntityTypeBase является типом одного из объектов в модели, значит, у EF6 нет свойства KeyMembers.
EntityFramework 6 Как получить поле идентификации с отражением?
Ответ 1
Я не думаю, что можно получить первичные ключи только путем отражения.
Во-первых, давайте узнаем, как EF определяет, какое свойство (и) будет являться первичным ключом (-ами) независимо от порядка/приоритета
Соглашение с Entity Framework для первичных ключей:
- Ваш класс определяет свойство с именем "ID" или "Id"
- или имя класса, за которым следуют "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)));
Это трудная задача, modelBuilder
инкапсулируется в OnModelCreating
, и даже если мы сохраним modelBuilder
где-то как свойство field/property, все еще сложно извлечь ключ из функции 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);