Include()
работает с результатами запроса, а не с промежуточными запросами. Вы можете прочитать больше о Include()
в этом посте. Поэтому одним из решений является применение Include()
ко всему запросу, например:
var q = ((from cp in _connectedClientRepository.GetConnectedClients()
.AsExpandable()
.Where(predicate)
select cp.LogEntry)
as ObjectQuery).Include("GameFile").ToList();
Это, вероятно, будет работать , но это ужасно. Можем ли мы сделать лучше?
Я могу придумать два пути решения этой проблемы. В основном это зависит от того, действительно ли вам нужны возвращаемые типы сущностей. Я не могу сказать, так ли это, не видя остальную часть вашего кода. Как правило, вам нужно возвращать типы сущностей, когда вы собираетесь обновить (или иным образом изменить) их. Если вы выбираете для целей просмотра или расчета, часто лучше возвращать POCO вместо типов сущностей. Вы можете сделать это с помощью projection , и, конечно, это работает в EF 1. В этом случае вы должны изменить свой метод репозитория, чтобы он возвращал типы POCO:
public IQueryable<ClientInfo> GetConnectedClients()
{
return from cp in _context.Clients
where // ...
select new ClientInfo
{
Id = cp.Id,
ClientName = cp.ClientName,
LogEntry = new LogEntryInfo
{
LogEntryId = cp.LogEntry.LogEntryId,
GameFile = new GameFileInfo
{
GameFileId = cp.LogEntry.GameFile.GameFileId,
// etc.
},
// etc.
},
// etc.
};
}
Обратите внимание, что при использовании проецирования не требуется никакой активной загрузки, отложенной загрузки и явной загрузки. Существует только ваше намерение, выраженное в виде запроса. Поставщик LINQ определит, что вам нужно, , даже если вы в дальнейшем составите запрос вне хранилища!
С другой стороны, вам может потребоваться возвращать типы сущностей вместо POCO, потому что вы намереваетесь их обновить. В этом случае я бы написал отдельный метод хранилища для LogEntries, как предложил Томас. Но я сделал бы это, только если бы намеревался обновить их, и я мог бы написать это как метод обновления, а не как метод «Get».