EF6:带有连接和分组的LINQ正在生成一个巨大的查询

时间:2017-05-16 04:32:46

标签: c# sql entity-framework linq-to-entities

我为实体框架编写了一个LINQ查询。结果是正确的,但生成的查询是巨大的,从长远来看,我有点担心性能。

这些是我的数据库表:

Employee     Employee_Position    Position
----------   ------------------   ------------
id           id                   id
firstname    employee_id          name
lastname     position_id          description
gender
birthdate
street
zipcode 
city
phonenr
email

我在其中存储查询最终结果的对象列表如下所示:

class EmployeesDTO
{
    public int id { get; set; }
    public string firstname { get; set; }
    public string lastname { get; set; }
    public string city { get; set; }
    public string phonenr { get; set; }

    public List<string> positionslist { get; set; }
    public string positions
    {
        get
        {
           positionslist.Sort();
           return String.Join(", ", positionslist);
        }
    }
}

它基本上是一个员工列表,其中包含逗号分隔的职位列表(多对多,一个员工可以有多个职位,多个员工可以拥有相同的职位)。

我在EF6上使用以下LINQ查询:

var q = from m in db.Employees
join ep in db.Employee_Position on m.id equals ep.employee_id
join p in db.Positions on ep.position_id equals p.id
group p.name by new { m.id, m.firstname, m.lastname, m.city, m.phonenr } into g
select new EmployeesDTO
{
    id = g.Key.id,
    firstname = g.Key.firstname,
    lastname = g.Key.lastname,
    city = g.Key.city,
    phonenr = g.Key.phonenr,
    positionslist = g.ToList()
};
return q.ToList();

这是生成一个大型SQL查询:

SELECT
`Project2`.`id`, 
`Project2`.`firstname`, 
`Project2`.`lastname`, 
`Project2`.`city`, 
`Project2`.`phonenr`, 
`Project2`.`C1`, 
`Project2`.`name`
FROM (SELECT
`Distinct1`.`id`, 
`Distinct1`.`firstname`, 
`Distinct1`.`lastname`, 
`Distinct1`.`city`, 
`Distinct1`.`phonenr`, 
`Join3`.`name`, 
CASE WHEN (`Join3`.`id` IS  NULL) THEN (NULL)  ELSE (1) END AS `C1`
FROM (SELECT DISTINCT 
`Extent1`.`id`, 
`Extent1`.`firstname`, 
`Extent1`.`lastname`, 
`Extent1`.`city`, 
`Extent1`.`phonenr`, 
FROM `Employees` AS `Extent1` INNER JOIN `Employee_Position` AS `Extent2` ON `Extent1`.`id` = `Extent2`.`employee_id`) AS `Distinct1` LEFT OUTER JOIN (SELECT
`Extent3`.`id`, 
`Extent3`.`firstname`, 
`Extent3`.`lastname`, 
`Extent3`.`gender`, 
`Extent3`.`birthdate`, 
`Extent3`.`street`,
`Extent3`.`zipcode`,  
`Extent3`.`city`, 
`Extent3`.`phonenr`, 
`Extent3`.`email`, 
`Extent4`.`id` AS `ID1`, 
`Extent4`.`employee_id`, 
`Extent4`.`position_id`, 
`Extent5`.`id` AS `ID2`, 
`Extent5`.`name`, 
`Extent5`.`description`, 
FROM `Employees` AS `Extent3` INNER JOIN `Employee_Position` AS `Extent4` ON `Extent3`.`id` = `Extent4`.`employee_id` INNER JOIN `Positions` AS `Extent5` ON `Extent4`.`functie_id` = `Extent5`.`id`) AS `Join3` ON (((((`Distinct1`.`id` = `Join3`.`id`) AND ((`Distinct1`.`firstname` = `Join3`.`firstname`) OR ((`Distinct1`.`firstname` IS  NULL) AND (`Join3`.`firstname` IS  NULL)))) AND ((`Distinct1`.`lastname` = `Join3`.`lastname`) OR ((`Distinct1`.`lastname` IS  NULL) AND (`Join3`.`lastname` IS  NULL)))) AND ((`Distinct1`.`city` = `Join3`.`city`) OR ((`Distinct1`.`city` IS  NULL) AND (`Join3`.`city` IS  NULL)))) AND ((`Distinct1`.`phonenr` = `Join3`.`phonenr`) OR ((`Distinct1`.`phonenr` IS  NULL) AND (`Join3`.`phonenr` IS  NULL)))) AS `Project2`
 ORDER BY 
`Project2`.`id` ASC, 
`Project2`.`firstname` ASC, 
`Project2`.`lastname` ASC, 
`Project2`.`city` ASC, 
`Project2`.`phonenr` ASC, 
`Project2`.`C1` ASC

最终结果很好(我得到了一个以逗号分隔的位置的EmployeeDBO列表),但这个查询看起来到处都是。它甚至选择了我不想要的字段(例如employee.gender,employee.birthdate,position.description等)。我已经尝试过调试它,问题似乎是由&#34;小组...&#34;一部分。

有什么方法可以提高效率吗?

0 个答案:

没有答案