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();
我有一个 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();