C# 是否有一种替代LINQ let操作符的方法不影响性能?
我有一个LINQ to实体查询,它使用select将原始数据从db转换为对象,并在过程中执行一些计算。这些计算重复了几次,所以我尝试重构LINQ以使用let。然而,在这样做的过程中,性能会受到极大的影响。是否有一种替代LET的方法,我可以仅用于代码的可重用性,而不影响性能C# 是否有一种替代LINQ let操作符的方法不影响性能?,c#,linq,linq-to-entities,C#,Linq,Linq To Entities,我有一个LINQ to实体查询,它使用select将原始数据从db转换为对象,并在过程中执行一些计算。这些计算重复了几次,所以我尝试重构LINQ以使用let。然而,在这样做的过程中,性能会受到极大的影响。是否有一种替代LET的方法,我可以仅用于代码的可重用性,而不影响性能 var defaultHours = 40; var defaultOldPersonPoints = 100; var defaultYoungPersonPoints = 50; // Example with no l
var defaultHours = 40;
var defaultOldPersonPoints = 100;
var defaultYoungPersonPoints = 50;
// Example with no let but lots of ugly, unreadable, redundant code
var exampleNoLet =
(from p in people
join op in otherPeople
on p.PersonId equals op.PersonId into inner
from outer in inner.DefaultIfEmpty(null)
select new
{
AllocatedPoints = (p.PersonTypeId == (int)PersonType.Old
? defaultOldPersonPoints
: p.PersonTypeId == (int)PersonType.Young
? defaultYoungPersonPoints : 0)
+ (int)(
(p.PersonTypeId == (int)PersonType.Old
? defaultOldPersonPoints
: p.PersonTypeId == (int)PersonType.Young
? defaultYoungPersonPoints : 0)
* (p.ContractedHours.HasValue
? (p.ContractedHours.Value - defaultHours) / defaultHours : 0))
});
// Using the LET allows me to clean up the code somewhat but causes a massive performance hit
var exampleUsingLet =
(from p in people
join op in otherPeople
on p.PersonId equals op.PersonId into inner
from outer in inner.DefaultIfEmpty(null)
let defaultPoints = p.PersonTypeId == (int)PersonType.Old
? defaultOldPersonPoints
: p.PersonTypeId == (int)PersonType.Young
? defaultYoungPersonPoints : 0
let contractedHourRatio = p.ContractedHours.HasValue
? (p.ContractedHours.Value - defaultHours) / defaultHours : 0
select new
{
AllocatedPoints = defaultPoints + (int)(defaultPoints * contractedHourRatio)
});
如果查询性能是问题,那么考虑将其移动到LINQ到对象。例如,目前,在投影中除了p没有使用任何东西。我不清楚为什么要做一个看起来像是左外连接的事情,事实上,你可以这样做:
var queryBase = from p in people
join op in otherPeople
on p.PersonId equals op.PersonId into inner
from outer in inner.DefaultIfEmpty(null)
select p;
var query = from p in queryBase.AsEnumerable() // <=== switch to LINQ-to-Objects
let defaultPoints = p.PersonTypeId == (int)PersonType.Old
? defaultOldPersonPoints
: p.PersonTypeId == (int)PersonType.Young
? defaultYoungPersonPoints : 0
let contractedHourRatio = p.ContractedHours.HasValue
? (p.ContractedHours.Value - defaultHours) / defaultHours : 0
select new
{
AllocatedPoints = defaultPoints + (int)(defaultPoints * contractedHourRatio)
});
在这里,SQL查询应该非常简单;所有复杂的工作都是在LINQtoObjor中执行的。 < P>如果查询性能是问题,那么考虑将其移动到LINQ到对象。例如,目前,在投影中除了p没有使用任何东西。我不清楚为什么要做一个看起来像是左外连接的事情,事实上,你可以这样做:
var queryBase = from p in people
join op in otherPeople
on p.PersonId equals op.PersonId into inner
from outer in inner.DefaultIfEmpty(null)
select p;
var query = from p in queryBase.AsEnumerable() // <=== switch to LINQ-to-Objects
let defaultPoints = p.PersonTypeId == (int)PersonType.Old
? defaultOldPersonPoints
: p.PersonTypeId == (int)PersonType.Young
? defaultYoungPersonPoints : 0
let contractedHourRatio = p.ContractedHours.HasValue
? (p.ContractedHours.Value - defaultHours) / defaultHours : 0
select new
{
AllocatedPoints = defaultPoints + (int)(defaultPoints * contractedHourRatio)
});
在这里,SQL查询应该非常简单;所有更复杂的工作都是在LINQ to Objects中完成的。您实际看过生成的SQL了吗?@SimonWhitehead虽然归根结底都是生成的SQL,但我对不影响生成的SQL的可读性感兴趣是的,但为什么它会影响性能?我们到底在做什么?知道这一点可能会给你一些答案,告诉你如何重构它,让它做同样的事情。。如果没有let,如果确实是let的原因……这个问题似乎是离题的,因为它假设问题与代码有关,而事实上它是环境问题,不再是问题。你真的看过生成的SQL吗?@SimonWhitehead,而这一切归结到生成的SQL,我对不影响生成的SQLYes的可读性感兴趣,但为什么它会影响性能呢?我们到底在做什么?知道这一点可能会给你一些答案,告诉你如何重构它,让它做同样的事情。。没有let如果确实是let的原因…这个问题似乎离题了,因为它假设问题与代码有关,而事实上它是环境问题,不再是问题。回顾这个问题,let版本现在比备用版本执行得更快。。。所以我的问题不再存在了。这可能是当时sql server实例的性能问题。因此,我尝试删除该问题,但由于您的回答,该问题不允许我回答。回顾该问题,let版本现在的执行速度比备用版本快。。。所以我的问题不再存在了。这可能是当时sql server实例的性能问题。因此,我尝试删除该问题,但由于您的回答,该问题不允许删除。