2013-07-09 2 views
1

У меня возникла проблема с созданием запроса (ну, я могу создать запрос, но Entity Framework прерывает его при попытке загрузить свойства).Включая дополнительное свойство навигации, в котором идентификатор свойства навигации совпадает с основным ключом объекта

У меня есть два объекта: Contact и ExternalContactExtension.

Контакт

ContactId

IsInternal

... некоторые другие данные ...

ExternalContactExtension

ContactId

... некоторые другие данные ...

Теперь contactId одинаково в обеих таблицах, но не все контакты являются внешними контактами (обозначенными IsInternal) и имеют внешнее контактное расширение.

Итак, проблема заключается в том, когда я запускаю запрос и пытаюсь включить расширение внешнего контакта. Поскольку ContactId является как основным ключом, так и внешним ключом, он не может быть недействителен. Я думаю, что EF считает, что это существует (хотя в свойствах навигации он указан в Zero или One). Это приводит к тому, что мои запросы прерываются, если у меня есть внутренние контакты, у которых нет внешних контактов.

Есть ли способ обойти это? Или мне нужно отдельно захватить объект расширения внешнего контакта?

Edit: Изображение моих моделей:

enter image description here

запросов, которые не удается (как правило, более фильтрация/включает в себя, но с включаемые ExternalContactExtension это единственное, что кажется, чтобы определить, если это не получится):

  DataSupplier.GetMany<Contact>(
       x => x.Active, 
       x => x.ExternalContactExtension 

       ).ToList(); 

определение GetMany (технически, называемый посредник класса, но это просто проходя по параметрам):

public virtual IEnumerable<TEntity> GetMany<TEntity>(Expression<Func<TEntity, bool>> where, params Expression<Func<TEntity, object>>[] includeProperties) 
     where TEntity : class 
    { 
     IDbSet<TEntity> set = this.context.Set<TEntity>(); 

     var query = set.IncludeMultiple(includeProperties).AsQueryable<TEntity>(); 

     query = query.Where(where); 
     this.queryString = ""; 
     this.queryString = query.ToString(); 
     List<TEntity> list = query.ToList(); 
     return list; 
    } 

Сообщение об ошибке:

enter image description here

Это на самом деле не бросать любые сообщений, пока вы не попытаетесь использовать свойство (тогда я получаю нулевое ссылочное исключение).

Другой редактировать:

Я сделал профиль SQL и EF правильно генерации SQL:

SELECT 
[Extent1].[ContactId] AS [ContactId], 
[Extent1].[EmployeeId] AS [EmployeeId], 
[Extent1].[IsInternal] AS [IsInternal], 
[Extent1].[GroupId] AS [GroupId], 
[Extent1].[OldSupplierId] AS [OldSupplierId], 
[Extent1].[Active] AS [Active], 
[Extent1].[InsertUserId] AS [InsertUserId], 
[Extent1].[InsertDate] AS [InsertDate], 
[Extent1].[UpdateUserId] AS [UpdateUserId], 
[Extent1].[UpdateDate] AS [UpdateDate], 
[Extent2].[ContactId] AS [ContactId1], 
[Extent2].[Salutation] AS [Salutation], 
[Extent2].[FirstName] AS [FirstName], 
[Extent2].[MiddleInitial] AS [MiddleInitial], 
[Extent2].[LastName] AS [LastName], 
[Extent2].[Phone] AS [Phone], 
[Extent2].[Fax] AS [Fax], 
[Extent2].[Title] AS [Title], 
[Extent2].[Department] AS [Department], 
[Extent2].[Email] AS [Email], 
[Extent2].[Address] AS [Address], 
[Extent2].[City] AS [City], 
[Extent2].[Territory] AS [Territory], 
[Extent2].[Country] AS [Country] 
FROM [DataSupplier].[Contact] AS [Extent1] 
LEFT OUTER JOIN [DataSupplier].[ExternalContactExtension] AS [Extent2] ON [Extent1].[ContactId] = [Extent2].[ContactId] 
WHERE [Extent1].[Active] = 1 

(Он правильно делает внешнее соединение, и это SQL действительно возвращается правильные результаты/он работает). Так что это где-то, где Entity Framework выполняет обработку, которая нарушает ее.

+0

Вы уверены, что свойство навигации настроено с «0..1» на «Контакты» и «1» на «ExternalContactExtension»? Если да, просьба указать дополнительную информацию о запрошенных прерываниях - трассировка стека, точное сообщение об ошибке и т. Д. – Bobson

+0

@Bobson Обновлено мое сообщение – CorrugatedAir

+0

Хорошее обновление! Работает ли он, если вы вынимаете строку 'x => x.ExternalContactExtension'? Или он все еще прерывается? – Bobson

ответ

0

На основе чата лучшим способом решения этой проблемы может быть создание «отсутствующего» поля ExternalContactExtensionID, которое может быть NULL.

Вы можете сделать это только с небольшим изменением базы данных. Создание вычисляемого поля и использовать формулу:

CASE WHEN IsExternal THEN ContactID ELSE NULL END 

Тогда EF увидит, что он ожидает, и все это должно быть хорошо.