I played with Linq in SQL to help me find a simple database. The database consists of two tables: “Player” and “Team”, and each player record has a team identifier for joining two tables (Player.TeamId → Team.Id).
To add a little complexity, the Team table contains historical data for the last 10 seasons. This means that each team can have up to 10 different entries in the team table pertaining to the 10 seasons presented.
I want my query to search for a player who returns a list of players matching the search criteria and a list of teammates for each of the returned players for that team this season.
Search criteria include first name, last name, (list) of seasons and team name.
My query looks like this:
using (var context = DataContextFactory.Context) { var playerList = context.GetTable<Player>(t => searchRequest.Seasons.Contains((int) t.Team.Season)) .Where(p => string.Equals(p.Surname, (searchRequest.Surname ?? p.Surname), StringComparison.OrdinalIgnoreCase) && string.Equals(p.Forename, (searchRequest.Forename ?? p.Forename), StringComparison.OrdinalIgnoreCase) && string.Equals(p.Team.Name, (searchRequest.TeamName ?? p.Team.Name), StringComparison.OrdinalIgnoreCase) )).ToList(); var teamMateList = new List<Player>(); foreach (var Player in playerList.Select(p => context.GetTable<Player>( tm => tm.Team.Id == p.Team.Id && tm.Id.CompareTo(p.Id) != 0))) { otherPeopleList.AddRange(people); } }
This works and returns a list of players (playerList) that match the search criteria, and for each of these players I can match my teammates from the second query results (teamMateList).
My problem is that Linq to SQL translates this into quite inefficient SQL. The first problem is that it selects the entire Player table from the database - I assume that this is due to the fact that Linq to SQL cannot translate Where clauses to standard SQL and therefore returns the entire table and does part of the query in the code
The second problem is that when executing the second query, Linq to SQL generates separate database queries for each playerList member. When reading the code, this probably makes sense, but I would have thought that Linq would be smart enough to translate it into a single query, which would lead to a more efficient search.
Any thoughts / suggestions on optimizing my query?