Linq join on objects with navigation 属性 - 如何提高性能

Linq join on objects with navigation property - how to improve performance

我有一个 Entity Framework 5 模型和 4 tables,我需要针对它们创建一个 LINQ 查询。我无法修改数据库结构,因为这是第 3 方数据库。

我当前的查询是:

_projectSites = (from de in _data.DataExchange
    join m in _data.Projects_MACO //combine exchange data and maco data
    on new
    {
        Number = de.number,
        IsProject = de.SiteType.Name != "opportunity"
    } equals
    new
    {
        Number = m.ProjectNumber == null ? m.OppNumber : m.ProjectNumber,
        IsProject = m.ProjectNumber != null
    }
    join d in _data.DataStores //and select only sites with datastores
    on new
    {
        Number = de.number
    } equals
    new
    {
        Number = d.SiteNumber
    }
    where de.Server.Name == _server
    select new ProjectSiteNode()
    {
        Server = de.Server.Name,
        ProjectNumber = de.number,
        Manager = m.ProjectNumber == null ? m.OMInitials : m.PMInitials,
        Exists = true,
        IsConfidential = de.confidential,
        Name = m.ProjectNumber == null ? m.OppTitle : m.ProjectTitle,
        ProjectType = de.SiteType.Name,// m.ProjectNumber == null ? "opportunity" : "project",
        Status = de.SiteState.Name
    }).Distinct().ToList();

有问题的行是:

 IsProject = de.SiteType.Name != "opportunity"

如何提高此查询的性能?

是否有机会预加载 de.SiteType.Name?我认为这个问题可能是因为它必须为每个 de 行创建一个对 SiteType table 的查询,对吗?

也许它与在 EF4 的连接语句中添加逻辑有关。如果你尝试会发生什么:

_projectSites = (from de in _data.DataExchange
    join m in _data.Projects_MACO //combine exchange data and maco data
    on new
    {
        Number = de.number
    } equals
    new
    {
        Number = m.ProjectNumber == null ? m.OppNumber : m.ProjectNumber
    }
    join d in _data.DataStores //and select only sites with datastores
    on new
    {
        Number = de.number
    } equals
    new
    {
        Number = d.SiteNumber
    }
    where de.Server.Name == _server 
    && de.SiteType.Name != "opportunity" 
    && m.ProjectNumber != null
    select new ProjectSiteNode()
    {
        Server = de.Server.Name,
        ProjectNumber = de.number,
        Manager = m.ProjectNumber == null ? m.OMInitials : m.PMInitials,
        Exists = true,
        IsConfidential = de.confidential,
        Name = m.ProjectNumber == null ? m.OppTitle : m.ProjectTitle,
        ProjectType = de.SiteType.Name,// m.ProjectNumber == null ? "opportunity" : "project",
        Status = de.SiteState.Name
    }).Distinct().ToList();

我终于找到了解决方案!!哇。问题出在!="opportunity"。如果我使用 ID 而不是字符串,则需要 0.2s 而不是 28s

var projectSites = (from d in _data.DataStores
                                     join de in _data.DataExchange
                                     on new
                                     {
                                         Number = d.SiteNumber
                                     } equals
                                     new
                                     {
                                         Number = de.number
                                     }
                                     join m in _data.Projects_MACO //combine exchange data and maco data
                                     on new
                                     {
                                         Number = de.number,
                                         IsProject = de.SiteType.ID != 2
                                     } equals
                                     new
                                     {
                                         Number = m.ProjectNumber == null ? m.OppNumber : m.ProjectNumber,
                                         IsProject = m.ProjectNumber != null
                                     }

                                     where de.Server.Name == _server
                                     select new 
                                     {
                                         Server = de.Server.Name,
                                         ProjectNumber = de.number,
                                         Manager = m.ProjectNumber == null ? m.OMInitials : m.PMInitials,
                                         Exists = true,
                                         IsConfidential = de.confidential,
                                         Name = m.ProjectNumber == null ? m.OppTitle : m.ProjectTitle,
                                         ProjectType = de.SiteType.Name,// m.ProjectNumber == null ? "opportunity" : "project",
                                         Status = de.SiteState.Name
                                     }).Distinct().ToList();