Linq连接具有导航属性的对象 - 如何提高性能

时间:2016-03-22 11:23:12

标签: c# linq entity-framework-5

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

我目前的查询是:

_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表查询,我是对的吗?

2 个答案:

答案 0 :(得分:0)

也许它可以在EF4的join-statement中添加逻辑。如果你尝试会发生什么:

_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();

答案 1 :(得分:0)

最后我找到了解决方案 !!哇。问题出在!=“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();