Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Linq或SQL中递归调用Where子句_C#_.net_Sql Server_Linq - Fatal编程技术网

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进行三次排序。