2015-03-06 3 views
1

У меня есть модель, как Человек, которые могут жить на улице и Улица находится в Сити и город в это свою очередь, находится в Страна. Также есть некоторые ActivityRecords для некоторых Персоны.Entity Framework теряет след навигационных свойств после «более применять»

public class Country 
{ 
    [Key] 
    public int id { get; set; } 
    public string name { get; set; } 
} 
public class City 
{ 
    [Key] 
    public int id { get; set; } 
    public string name { get; set; } 

    [ForeignKey("Country")] 
    public int country_id { get; set; } 
    public virtual Country Country { get; set; } 
} 
public class Street 
{ 
    [Key] 
    public int id { get; set; } 
    public string name { get; set; } 

    [ForeignKey("City")] 
    public int city_id { get; set; } 
    public virtual City City { get; set; } 
} 

public class Person 
{ 
    [Key] 
    public int id { get; set; } 

    ForeignKey("Street")] 
    public int? street_id { get; set; } 
    public virtual Street Street { get; set; } 

    //no connection to ActivityRecord[] 
} 

public class ActivityRecord 
{ 
    [Key] 
    public int id { get; set; } 
    public string desc { get; set; } 

    [ForeignKey("Person")] 
    public int? person_id { get; set; } 
    public virtual Person Person { get; set; } 
} 

Мне нужно перечислить часть информации лиц, в том числе их адреса до страны плюс один из видов деятельности, если есть какая-либо (в противном случае нуль). Я намеренно сбросил все детали и столбцы, чтобы упростить пример.

Итак, я пришел к этому в моем коде:

context.Persons.AsNoTracking().OrderBy(p => p.id).Skip(0).Take(10).GroupJoin(
    context.ActivityRecords, 
    p => p.id, 
    ar => ar.person_id, 
    (p, ar) => new { p = p, ar = ar.FirstOrDefault() } //join 1 or 0 entries 
).Select(result => new 
{ 
    id = result.t.id, 
    street = result.t.Street.name, 
    city = result.t.Street.City.name, 
    country = result.t.Street.City.Country.name 
}).ToArray(); 

Когда я проверяю EF-сгенерированный запрос, я вижу, левые внешний присоединяется на одной таблиц несколько раз (улицы, города):

SELECT 
    [Limit1].[id] AS [id], 
    [Extent3].[name] AS [name], 
    [Extent5].[name] AS [name1], 
    [Extent8].[name] AS [name2] 
    FROM   (SELECT TOP (10) [Extent1].[id] AS [id], [Extent1].[street_id] AS [street_id] 
     FROM (SELECT [Extent1].[id] AS [id], [Extent1].[street_id] AS [street_id], row_number() OVER (ORDER BY [Extent1].[id] ASC) AS [row_number] 
      FROM [dbo].[Persons] AS [Extent1] 
     ) AS [Extent1] 
     WHERE [Extent1].[row_number] > 0 
     ORDER BY [Extent1].[id] ASC) AS [Limit1] 
    OUTER APPLY (SELECT TOP (1) [Extent2].[id] AS [id] 
     FROM [dbo].[ActivityRecords] AS [Extent2] 
     WHERE [Limit1].[id] = [Extent2].[person_id]) AS [Limit2] 
    LEFT OUTER JOIN [dbo].[Streets] AS [Extent3] 
      ON [Limit1].[street_id] = [Extent3].[id] 
    LEFT OUTER JOIN [dbo].[Streets] AS [Extent4] /* <-- Seriously? */ 
      ON [Limit1].[street_id] = [Extent4].[id] 
    LEFT OUTER JOIN [dbo].[Cities] AS [Extent5] 
      ON [Extent4].[city_id] = [Extent5].[id] 
    LEFT OUTER JOIN [dbo].[Streets] AS [Extent6] /* <-- Come on! */ 
      ON [Limit1].[street_id] = [Extent6].[id] 
    LEFT OUTER JOIN [dbo].[Cities] AS [Extent7] /* <-- Hey! */ 
      ON [Extent6].[city_id] = [Extent7].[id] 
    LEFT OUTER JOIN [dbo].[Countries] AS [Extent8] 
      ON [Extent7].[country_id] = [Extent8].[id] 

Когда я только удалить одно соединение строки в группе присоединиться к

... (р, аг) => новый {р = р, ар = ар} ...

он отлично работает и соединяется с каждой таблицей один раз.

Я попытался включить таблицы до присоединиться, но без успеха. Единственное, что нужно сделать, это сделать выбор всех человек-города-города до присоединяйтесь к, но проблема в том, что он загружает все эти записи до, разрезая TOP 10, и на самом деле у меня там много тяжелых рассчитанные столбцы (этот запрос, когда проблема все еще видно, гораздо проще, если вы удалите Skip() и Take(), но оставить GroupJoin() с FirstOrDefault()).

Итак, мой вопрос: как сообщить EF, чтобы не включать одни и те же таблицы несколько раз, есть ли обходной путь? Почему он начинает потерять отслеживание цепочки свойств навигации после однострочного соединения?

ответ

1

Это была действительно ошибка в EF компиляции запросов, так что переход от EF 6.1.1 в EF 6.1.2 исправили проблему.

Смежные вопросы