(Сначала модель EF6) Как получить значение внешнего ключа без доступа к свойству навигации, чтобы мне не нужно было загружать весь объект?

Как я могу получить значение внешнего ключа без доступа к свойству навигации, чтобы мне не нужно было загружать весь объект?

public class A
{
   public int Id {get;set;}
   // ...
}
public class B
{
   public virtual A A {get;set;}
   // ...
}
int idOfA = MyB.A.Id;   // slow way of doing it.

Я использую Entity Framework 6 ModelFirst+DbContext в VS2012. Раньше я использовал старую версию EF+ModelFirst+ObjectContext. Я укусил пулю и мигрировал, создав модель из старой базы данных.

Получение ключа сущности было возможно со старым ObjectContext:

EntityReference<EntityType> reference = MyB.AReference; // AReference was generated by EF
int id = (int)reference.EntityKey.EntityKeyValue[0].Value;

Но теперь генератор кода больше не генерирует EntityReferences для каждого свойства навигации One или ZeroOrOne.

Итак, как я могу получить внешний ключ в EF6+DbContext?

Вот несколько идей того, что я пытался/мог бы сделать, но потерпел неудачу/не хотел:

  1. Я мог бы просто проигнорировать плохую производительность и загрузить полный объект, чтобы получить его первичный ключ.
  2. Использование атрибута [ForeignKey] или Fluent API EF. Но я не знаю, как я могу и должен ли я это делать. Возможно, это даже не работает с первым подходом модели, потому что «OnModelCreated» не вызывается.
  3. Я изменяю сопоставление базы данных и сущности (материал xml в коде edmx), чтобы для каждого внешнего ключа было сопоставлено дополнительное свойство (public int *Id {get;set;}). Но я никогда этого не делал и не знаю, с чего начать читать.
  4. Когда я создал первую модель EF 6.0 из своей старой базы данных, была опция «Включить столбцы внешнего ключа в модель». Я не активировал это в прошлый раз, что, оглядываясь назад, было неправильным. Но сделать это снова потребовало бы много работы (ручная настройка наследования сущностей и т. д.).
  5. Использование менеджера отношений. Но мои сгенерированные сущности больше не реализуют интерфейс IEntityWithRelationships. Хотя я думаю, что удовлетворяю условиям для прокси и я проверил в отладчике, что создаются классы прокси. (изменить: у кого-то была аналогичная проблема с IEntityWithRelationships+IEntitiyWithChangeTracker. См. решение в комментариях к этому вопросу.)

person Ralf    schedule 12.04.2017    source источник


Ответы (1)


Вот код, который я использую (при условии, что это не Model First, но в нем нет ничего конкретного для обоих подходов). В образце у меня есть товары, и каждому товару принадлежит категория. Вот как я могу запросить CategoryId в объекте Product без загрузки Category:

Model1 context = new Model1();
var product = context.Products.First();
RelationshipManager relMgr = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager.GetRelationshipManager(product);
IEnumerable<IRelatedEnd> relEnds = relMgr.GetAllRelatedEnds();
IRelatedEnd relEnd = relEnds.Where(r => r.RelationshipName.EndsWith("Product_Category")).Single();
EntityReference<Category> entityRef = relEnd as EntityReference<Category>;
var entityKey = entityRef.EntityKey;
int categoryId = (int)entityKey.EntityKeyValues[0].Value;
person Akos Nagy    schedule 12.04.2017