Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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 where条款;如果项不为空,则计算,否则,获取所有数据;_C#_Linq - Fatal编程技术网

C# Linq where条款;如果项不为空,则计算,否则,获取所有数据;

C# Linq where条款;如果项不为空,则计算,否则,获取所有数据;,c#,linq,C#,Linq,我正试图在一个web客户端上实现一个过滤器表单,它可以有任意数量的条目被填写或清空。我的WebAPI方法将采用一个包含表单所有属性的模型,如下所示: RequisitionType (enum: RequisitionType.RequisitionedBy, RequisitionType.CreatedBy) Vendor (string or null) Plant (string or null) CompanyCode (string or null) CreatedFrom (dat

我正试图在一个web客户端上实现一个过滤器表单,它可以有任意数量的条目被填写或清空。我的WebAPI方法将采用一个包含表单所有属性的模型,如下所示:

RequisitionType (enum: RequisitionType.RequisitionedBy, RequisitionType.CreatedBy)
Vendor (string or null)
Plant (string or null)
CompanyCode (string or null)
CreatedFrom (datetime)
CreatedTo (datetime)
如果(条件){filter},我如何在没有许多疯狂的
的情况下实现linq查询

我尝试过类似的方法,首先检查过滤器是否有值,如果有,我会将字段与该值进行比较,否则我会将字段与自身进行比较,但编译器不允许这样做

在下面的示例中,
model
是从客户端传递给控制器的内容

var data =  logic.GetPurchaseReqs()
            .Where(pr => {
                model.RequisitionType == RequisitionType.RequisitionedBy ? pr.PrReqId.ToUpper() == model.Username.ToUpper() : pr.PrReqId.ToUpper() == pr.PrReqId.ToUpper()
                && model.RequisitionType == RequisitionType.CreatedBy ? pr.PrCreId.ToUpper() == model.Username.ToUpper() : pr.PrCreId.ToUpper() == pr.PrCreId.ToUpper()
                && model.Vendor != null ? pr.Vendor == model.Vendor : pr.Vendor == pr.Vendor
                [etc...]
            })
            .ToList();

这就是我将它编程为的内容。请注意缺少括号以及我处理请购单类型的方式。这假设请购单类型不能为null…如果可以…则必须添加第三个条件
| | model.requisiontype==null
。否则,您检查的每个条件都会作为另一个条件添加到另一个
&&(条件!=null?条件检查:true)


我们的目标是设置=>的右侧,以便向下计算为单个布尔值true/false。您应该能够对任何给定值(pr)的语句进行求值,并得到正确或错误的结果。

我认为简化此过程的最简单方法是:

logic.GetPurchaseReqs()
     .Where(pr => model.RequisitionType != RequisitionType.RequisitionedBy || pr.PrReqId.ToUpper() == model.Username.ToUpper())
     .Where(pr => model.RequisitionType != RequisitionType.CreatedBy || pr.PrCreId.ToUpper() == model.Username.ToUpper())
     .Where(pr => model.Vendor == null || pr.Vendor == model.Vendor)
     //[...]
     .ToList();

请注意,添加几个
Where
子句会带来很小的开销(只是JIT调用函数所需的处理能力),但IMHO会提高可读性。

对于可读性,由于代码量几乎相同,我肯定会采用
if(condition)
解决方案

var data = logic.GetPurchaseReqs(); //.AsEnumerable() migt be needed here

if(model.RequisitionType == RequisitionType.RequisitionedBy)
  data = data.Where(pr => pr.PrReqId.ToUpper() == model.Username.ToUpper())

if(model.Vendor != null)
  data = data.Where(pr => pr.Vendor == model.Vendor);

if(model.CompanyCode != null)
  data = data.Where(pr => pr.CompanyCode == model.CompanyCode);

...

不是完全按照你想做的事情,而是基于你的头衔:

var data = logic.GetPurchaseReqs();

if(condition)
{
    data = data.Where(pr => pr.... etc
}

var result = data.ToList();

最好的解决方案是为linq创建一个扩展方法。它将接受一个条件语句和一个where表达式,如果条件为true,它将使用where表达式,否则将跳过它。这可以极大地清理代码,消除对if语句的需要

public static class LinqExtension
{
    public static IQueryable<T> Where<T>(this IQueryable<T> query, bool condition, Expression<Func<T, bool>> whereClause)
    {
        if (condition)
        {
            return query.Where(whereClause);
        }
        return query;
    }
}
var data = logic.GetPurchaseReqs()
                .Where(model.RequisitionType == RequisitionType.RequisitionedBy, pr => pr.PrReqId.ToUpper() == model.Username.ToUpper())
                .Where(model.Vendor != null, pr => pr.Vendor == model.Vendor)
                .Where(model.CompanyCode != null, pr => pr.CompanyCode == model.CompanyCode);

您可能希望返回
true
expr,而不是尝试将项目与自身进行比较?比较:true
。返回true会更好。在这种情况下,使用括号时需要非常小心。确保结构正确,即使这意味着要添加许多单独的括号集。这可能是编译器的抱怨,你在某个地方被抵消了。
var data = logic.GetPurchaseReqs()
                .Where(model.RequisitionType == RequisitionType.RequisitionedBy, pr => pr.PrReqId.ToUpper() == model.Username.ToUpper())
                .Where(model.Vendor != null, pr => pr.Vendor == model.Vendor)
                .Where(model.CompanyCode != null, pr => pr.CompanyCode == model.CompanyCode);