C# 对多个可能的可空值组合执行Linq操作

C# 对多个可能的可空值组合执行Linq操作,c#,asp.net-mvc,linq,entity-framework,C#,Asp.net Mvc,Linq,Entity Framework,标题和方法几乎解释了每一件事。我需要在多个选项的基础上执行搜索。我不想写所有可能的条件。有什么建议吗 public List<Ticket> GetTickets(Status? status,Priority? priority,TicketLevel? ticketLevel, DateTime? createdOn,DateTime? modifiedOn,bool? removed) { if(status!=null &&am

标题和方法几乎解释了每一件事。我需要在多个选项的基础上执行搜索。我不想写所有可能的条件。有什么建议吗

public List<Ticket> GetTickets(Status? status,Priority? priority,TicketLevel? ticketLevel,
        DateTime? createdOn,DateTime? modifiedOn,bool? removed)
    {
        if(status!=null && priority !=null && ticketLevel!=null && createdOn==null && modifiedOn==null && removed ==null)
        {
            using (CRMContext context=new CRMContext())
            {
                return context.Tickets.Where(
                    t => t.Status == status && t.Priority == priority && t.TicketLevel == ticketLevel).ToList();
            }
        }
        throw new NotImplementedException();
    }

谢谢大家!

我认为最好的方法是将查询分成几个部分:

public List<Ticket> GetTickets(Status? status,Priority? priority,TicketLevel? ticketLevel, DateTime? createdOn,DateTime? modifiedOn,bool? removed)
{
    using (CRMContext context=new CRMContext())
    {
        var query = context.Tickets.Select(t => t);

        if(status != null)
            query = query.Where(t => t.Status == status);

        if(priority != null)
            query = query.Where(t => t.Priority == priority);

        if(ticketLevel != null)
            query = query.Where(t => t.TicketLevel == ticketLevel);

        //.... More conditions...

        return query.ToList();
    }
}

您可以使用Dave Bish的解决方案,或者在这里使用三元运算符

return context.Tickets.Where(t =>
                (status != null ? t.Status == status : true) &&
                (priority != null ? t.Priority == priority : true) &&
                (ticketLevel != null ? t.TicketLevel == ticketLevel : true)).ToList();
两者都有明显的优势。Dave提供的解决方案具有可读性/维护性的优点。缺点是它是链接的,因此只能是and&&条件

这里的解决方案还可以将&&运算符更改为| |。缺点在于可读性/易于维护


就个人而言,选择哪一个取决于您。

此解决方案的另一个优点是,您最终可编译的查询文件更少。@Aron这确实是一个很好的观点,编辑了一段说明了这一点,感谢您指出@Aron这是否意味着优势仅在编译时才有意义?我想看更多关于你观点的解释。当创建IQueryable时,它需要通过实体框架转换并编译成SQL。从.net 4.5开始,EF SQL将被缓存。在许多EF查询中,SQL编译实际上占据了大部分运行时。@EBrown只有在您迭代查询并获得其结果时才会编译查询。因为中间查询的结果没有被计算,所以它们实际上没有被编译成SQL。工作起来很有魅力,比t-SQLLet-me-check中的@param=null或t.field=@param模式效率更高。。我很快就会回来。非常感谢。