如何将多标准搜索应用于LINQ?

时间:2011-03-11 04:59:31

标签: c# .net linq

我有一个带有4个组合框的WebForm,允许用户定义不同的搜索条件。如果用户在组合框中没有选择任何内容,则表示用户想要选择此条件中的所有数据(换句话说,省略过滤器)

这个想法很简单,但是当我在Linq中实现它时,它很痛苦。我不知道如何选择在查询中添加条件。这是我的“概念”查询,当然,这不起作用:

var context = new Entities();
        var complaints = from c in context.Complaints
                         join s in context.Statuses on c.Status equals s.Id
                         join service in context.SERVICES on c.ServiceId equals service.Id
                         join u in context.Users on c.CreatedBy equals u.UserId
                         from technician in context.Users.Where(technician => technician.UserId == c.AssignedTo).DefaultIfEmpty()
                         where c.ResellerId == CurrentUser.ResellerID
                         && c.CreatedBy == (decimal)ASPxComboBoxSupporter.Value //if Supporter is selected and so on
                         && c.AssignedTo == (decimal)ASPxComboBoxTechnician.Value
                         && c.ServiceId == (decimal)ddlService.Value
                         && c.Status == (decimal)ddlStatus.Value
                         select new
                         {
                             c.Id,
                             c.Status,
                             s.Name,
                             c.ServiceId,
                             Service = service.Name,
                             c.Title,
                             c.Customer,
                             c.Description,
                             c.CreatedDate,
                             c.CreatedBy,
                             Author = u.Username,
                             c.AssignedBy,
                             c.AssignedTo,
                             Technician = technician.Username,
                             c.AssignedDate
                         };

我该怎么做?

3 个答案:

答案 0 :(得分:3)

您可以尝试利用IQueryable对象的工作方式,而不是使用更多SQL样式的Linq语法创建它(抱歉我不知道它的正确名称)。基本上你可以做的是在必要时添加where子句,否则省略它们。这些方面应该有用:

var context = new Entities();
var complaints = from c in context.Complaints
                 join s in context.Statuses on c.Status equals s.Id
                 join service in context.SERVICES on c.ServiceId equals service.Id
                 join u in context.Users on c.CreatedBy equals u.UserId
                 from technician in context.Users.Where(technician => technician.UserId == c.AssignedTo).DefaultIfEmpty()
                 select new
                 {
                     c.Id,
                     c.Status,
                     s.Name,
                     c.ServiceId,
                     Service = service.Name,
                     c.Title,
                     c.Customer,
                     c.Description,
                     c.CreatedDate,
                     c.CreatedBy,
                     Author = u.Username,
                     c.AssignedBy,
                     c.AssignedTo,
                     Technician = technician.Username,
                     c.AssignedDate
                 };

所以请记住,您还没有实际查询任何内容,因为Linq使用延迟执行。现在你可以通过并添加where子句

if (ASPxComboBoxSupporter.Value != null)
{
    complaints = complaints.Where(c => c.CreatedBy == (decimal)ASPxComboBoxSupporter.Value);
}
if (ASPxComboBoxTechnician.Value != null)
{
    complaints = complaints.Where(c => c.AssignedTo == (decimal)ASPxComboBoxTechnician.Value);
}

if (ddlService.Value != null)
{
    complaints = complaints.Where(c => c.ServiceId == (decimal)ddlService.Value);
}

if (ddlStatus.Value != null)
{
    complaints = complaints.Where(c => c.Status == (decimal)ddlStatus.Value);
}

我没有对此进行过测试,所以如果有什么东西不能正常工作,请告诉我。

答案 1 :(得分:1)

首先,您必须解析用户输入的文本以查看它是否真的是一个数字,如果是,则将其转换为decimal类型。有一个方便的方法decimal.TryParse

    decimal supporter;
    bool supportedSpecified = decimal.TryParse( ASPxComboBoxSupporter.Value, out supporter );

然后您可以在查询中使用此信息:

    where c.ResellerId == CurrentUser.ResellerID
    && ( !supporterSpecified || c.CreatedBy == supporter )
    ...

重复其他标准。

答案 2 :(得分:1)

在Nutshell书中查看C#中描述的the PredicateBuilder class。它允许您动态构建谓词以与LINQ to SQL和Entity Framework一起使用。