Linq2Sql: query - subquery optimisation
I have the following query:
IList<InfrStadium> stadiums =
(from sector in DbContext.sectors
where sector.Type=typeValue
select new InfrStadium(sector.TeamId)
).ToList();
and InfrStadium class constructor:
private InfrStadium(int teamId)
{
IList<Sector> teamSectors = (from sector in DbContext.sectors
where sector.TeamId==teamId
select sector)
.ToList<>();
... work with data
}
Current implementation perform 1+n queries, where n - number of records fetched the 1st time.
I want to optimize that.
And another one I would love to do using 'group' operator in way like this:
IList<InfrStadium> stadiums =
(from sector in DbContext.sectors
group sector by sector.TeamId into team_sectors
select new InfrStadium(team_sectors.Key, team_sectors)
).ToList();
with appropriate constructor:
private InfrStadium(int iTeamId, IEnumerable<InfrStadiumSector> eSectors)
{
IList<Sector> teamSectors = eSectors.ToList();
... work with data
}
But attempt to launch query causes the following error:
Expression of type 'System.Int32' cannot be used for constructor parameter of type 'System.Collections.Generic.IEnumerable`1[InfrStadiumSector]'
Question 1:
Could you please explain, what is wrong here, I don't understand why 'team_sectors' is applied as 'System.Int32'?
I've tried to change query a little (replace IEnumerable with IQueryeable):
IList<InfrStadium> stadiums =
(from sector in DbContext.sectors
group sector by sector.TeamId into team_sectors
select new InfrStadium(team_sectors.Key, tea开发者_JAVA技巧m_sectors.AsQueryable())
).ToList();
with appropriate constructor:
private InfrStadium(int iTeamId, IQueryeable<InfrStadiumSector> eSectors)
{
IList<Sector> teamSectors = eSectors.ToList();
... work with data
}
In this case I've received another but similar error:
Expression of type 'System.Int32' cannot be used for parameter of type 'System.Collections.Generic.IEnumerable
1[InfrStadiumSector]' of method 'System.Linq.IQueryable
1[InfrStadiumSector] AsQueryableInfrStadiumSector'
Question 2:
Actually, the same question: can't understand at all what is going on here...
P.S. I have another to optimize query idea (describe here: Linq2Sql: query optimisation) but I would love to find a solution with 1 request to DB).
First, pull the data locally and put it into a structure that meets your needs.
ILookup<int, InfrStadiumSector> sectorLookup =
(
from sector in DbContext.sectors
where sector.Type == typeValue
select sector
).ToLookup(sector => sector.TeamId);
Then project each grouping in that lookup into an instance of InfrStadium (without going back to the database)...
IList<InfrStadium> stadiums = sectorLookup
.Select(x => new InfrStadium(x.Key, x))
.ToList();
And that projection uses this constructor.
private InfrStadium(int iTeamId, IEnumerable<InfrStadiumSector> eSectors)
I can't be sure what's going on without a little experimentation. Are you sure of the order of your parameters in the constructor? If so, then it might be a problem translating the expression. You might want to try materializing the query before you attempt to construct the InfrStadium
objects. I'll rewrite using extension methods as I think it will be easier to read.
var stadiums = DbContext.sectors
.ToLookup( s => s.TeamId )
.Select( g => new InfrStadium( g.Key, g ) )
.ToList();
精彩评论