C# 如何在Linq或SQL中递归调用Where子句
假设我有以下过滤器参数:C# 如何在Linq或SQL中递归调用Where子句,c#,.net,sql-server,linq,C#,.net,Sql Server,Linq,假设我有以下过滤器参数: Type="Student" School = "High" ReferenceID = "123abc" PaymentOnFile= "Y" 现在,我需要根据这4个参数找到第一个学生。如果没有找到学生,则我需要根据3个参数找到他们,如果没有找到学生,则使用2个参数,以此类推 以下是我当前的代码: var Student = db.Students.Where(x=> x.School == School && x.Type ==
Type="Student"
School = "High"
ReferenceID = "123abc"
PaymentOnFile= "Y"
现在,我需要根据这4个参数找到第一个学生。如果没有找到学生,则我需要根据3个参数找到他们,如果没有找到学生,则使用2个参数,以此类推
以下是我当前的代码:
var Student = db.Students.Where(x=> x.School == School && x.Type == Type && x.ReferenceID == ReferenceID && x.PaymentOnFile == PaymentOnFile).FirstOrDefault();
if (Student == null)
{
Student = db.Students.Where(x=> x.School == School && x.Type == Type && x.ReferenceID == ReferenceID).FirstOrDefault();
}
if (Student == null)
{
Student = db.Students.Where(x=> x.School == School && x.Type == Type).FirstOrDefault();
}
if (Student == null)
{
Student = db.Students.Where(x=> x.School == School).FirstOrDefault();
}
return Student;
这是可行的,但它不是非常有效和丑陋。有什么更好的方法可以做到这一点?也许是使用表达式树或其他什么,但我无法理解
SQL也可以工作 我认为这样做会奏效:
var student = db.Students
.Where(x => x.School == school)
.OrderBy(x => (x.Type == type) ? 0 : 1)
.ThenBy(x => (x.ReferenceID == referenceId) ? 0 : 1)
.ThenBy(x => (x.PaymentOnFile == paymentOnFile) ? 0 : 1)
.FirstOrDefault();
我想如果你能应用这个查询逻辑,它可以更好地帮助你
SELECT TOP 1
*
FROM Student AS S
ORDER BY CASE
WHEN S.School = @School AND S.[Type] = @Type AND S.ReferenceID = @ReferenceID AND S.PaymentOnFile = @PaymentOnFile THEN
1
WHEN S.School = @School AND S.[Type] = @Type AND S.ReferenceID = @ReferenceID THEN
2
WHEN S.School = @School AND S.[Type] = @Type THEN
3
WHEN S.School = @School THEN
4
END ASC
这个动态解决方案将准确地执行您的递归逻辑,并在Linq和EF的情况下工作。您可以添加其他条件(到
谓词
,顺序事项),解决方案(循环的)将保持不变
var predicates = new List<Expression<Func<Student, bool>>>
{
x => x.School == "High",
x => x.Type == "Student",
x => x.ReferenceID == "123abc",
x => x.PaymentOnFile == "Y",
};
Student student = null;
for(var i = 0; i < predicates.Count; i++)
{
var query = db.Students.AsQueryable();
for (var j = 0; j < predicates.Count - i; j++)
query = query.Where(predicates[j]);
if ((student = query.FirstOrDefault()) != null)
break;
}
var谓词=新列表
{
x=>x.学校==“高”,
x=>x.类型==“学生”,
x=>x.ReferenceID==“123abc”,
x=>x.PaymentOnFile==“Y”,
};
Student=null;
for(var i=0;i
看起来很有趣,请检查。需要将性能与上述解决方案进行比较。@user194076我认为性能会更好,因为您应该执行一到三个简单的Where
查询,而不是在T-SQL构造时使用case进行三次排序。