我有两个类:Property和PropertyValue。属性具有多个值,其中每个值都是新修订。
检索一组属性时,我想包含每个属性的最新版本值。
在T-SQL中,这可以非常有效地完成:SELECT
p.Id,
pv1.StringValue,
pv1.Revision
FROM dbo.PropertyValues pv1
LEFT JOIN dbo.PropertyValues pv2 ON pv1.Property_Id = pv2.Property_Id AND pv1.Revision < pv2.Revision
JOIN dbo.Properties p ON p.Id = pv1.Property_Id
WHERE pv2.Id IS NULL
ORDER BY p.Id
此查询中的“魔术”是在小于条件的情况下连接并查找没有LEFT JOIN强制结果的行。
如何使用LINQ to EF完成类似的操作?
我能想到的最好的事情是:
from pv in context.PropertyValues
group pv by pv.Property into g
select g.OrderByDescending(p => p.Revision).FirstOrDefault()
它确实产生了正确的结果,但比另一个慢了约10倍。
答案 0 :(得分:1)
也许这会有所帮助。 db是数据库上下文:
(
from pv1 in db.PropertyValues
from pv2 in db.PropertyValues.Where(a=>a.Property_Id==pv1.Property_Id && pv1.Revision<pv2.Revision).DefaultIfEmpty()
join p in db.Properties
on pv1.Property_Id equals p.Id
where pv2.Id==null
orderby p.Id
select new
{
p.Id,
pv1.StringValue,
pv1.Revision
}
);
答案 1 :(得分:1)
在Linq To Entities中优化查询之后,您还必须了解Entity Framework将查询转换为SQL然后将结果映射回对象所需的工作。
将Linq To Entities查询直接与SQL查询进行比较将始终导致性能降低,因为实体框架为您做了更多工作。
因此,优化实体框架所采用的步骤也很重要。
可能有所帮助的事情:
答案 2 :(得分:0)
如果你想在连接中使用多个条件(小于表达式),你可以这样做
from pv1 in db.PropertyValues
join pv2 in db.PropertyValues on new{pv1.Property_ID, Condition = pv1.Revision < pv2.Revision} equals new {pv2.Property_ID , Condition = true} into temp
from t in temp.DefaultIfEmpty()
join p in db.Properties
on pv1.Property_Id equals p.Id
where t.Id==null
orderby p.Id
select new
{
p.Id,
pv1.StringValue,
pv1.Revision
}