Entity Framework: почему свойства навигации исчезают после группировки? - PullRequest
2 голосов
/ 11 февраля 2010

Я получаю коллекцию по следующему запросу:

var numbers = _betDetailItem.GetBetDetailItems().Where(betDetailItem => betDetailItem.BetDetail.Bet.DateDrawing == resultToCreate.Date && betDetailItem.BetDetail.Bet.Status == 1).Where(condition);

Прямо здесь я могу получить доступ к своим свойствам навигации и перемещаться по связанной информации. Обратите внимание, как я на самом деле использую их для фильтрации данных.

После того, как я сгруппирую результаты, свойства навигации станут нулевыми.

var grouped = numbers.GroupBy(p => p.BetDetail.Bet);
//Iterate through the collection created by the Grouping
foreach (IGrouping<Bet, BetDetailItem> group in grouped)
{
    var details = group.Key.BetDetails; //This is what doesn't work. BetDetails is a navigation property which was accessible in the previous query. 
}

Я что-то не так делаю?

Ответы [ 2 ]

1 голос
/ 12 февраля 2010

Вы путаете LINQ с сущностями и объектными операциями.

Это LINQ to Entities:

var numbers = _betDetailItem.GetBetDetailItems().Where(betDetailItem => betDetailItem.BetDetail.Bet.DateDrawing == resultToCreate.Date && betDetailItem.BetDetail.Bet.Status == 1).Where(condition);

Так это:

var grouped = numbers.GroupBy(p => p.BetDetail.Bet);

Это операции с объектами:

foreach (IGrouping<Bet, BetDetailItem> group in grouped)
{
    var details = group.Key.BetDetails; //This is what doesn't work. BetDetails is a navigation property which was accessible in the previous query. 
}

В LINQ to Entities никогда не нужно думать о загрузке связанных экземпляров. Вы всегда можете обратиться к любому свойству любого объекта. Однако в какой-то момент вы хотите выйти из мира LINQ to Entities в пространство объектов, потому что вы хотите работать с экземплярами типа BetDetail вместо типа IQueryable<BetDetail>. Это означает, что Entity Framework теперь требуется для генерации SQL для извлечения данных из базы данных. На этом этапе не видно, к каким связанным экземплярам вы будете обращаться позже в своем коде. Ничто в вашем запросе LINQ to Entities не заставляет загружать связанный Bet. Поэтому, если вы не сделаете что-то, что заставит его загрузиться, например, воспользуетесь энергичной загрузкой, явной загрузкой или отложенной загрузкой EF 4, оно не будет загружено.

Использование отложенной загрузки (например, в Entity Framework 4 или в другом ORM) сделает этот код видимым для работы, но это будет излишне медленным из-за большого количества сгенерированных запросов к базе данных. Лучшим решением было бы использовать стремительную загрузку или проекцию . Таким образом, будет только одна поездка в БД.

1 голос
/ 11 февраля 2010

Как только вы наберете GroupBy(), вы больше не будете иметь дело со своими сущностями - они были ... ну, сгруппированы, так что var в var grouped = ... теперь имеет тип IEnumerable<IGrouping<.... Таким образом, методы, доступные для элементов в коллекции grouped, являются методами интерфейса IGrouping<>.

Вы можете захотеть OrderBy() вместо GroupBy(), в зависимости от ваших потребностей, или вам нужно будет выполнить итерацию на двух уровнях: итерацию по каждой группе в grouped и по каждому члену в каждом из них.

Когда вы находитесь внутри определенного IGrouping<>, вы должны иметь доступ к свойствам, которые вы ищете.

...