如何将多条件搜索应用于 LINQ?

发布于 2024-10-21 12:58:24 字数 1865 浏览 1 评论 0原文

我有一个带有 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
                         };

我怎样才能做到这一点?

I have a WebForm with 4 combo boxes, which allow user to define different search criteria. In case user selects nothing in a combo box, it does mean that user want to select all data in this criterion (in other words, omit the filter)

The idea is simple, but when I implement it in Linq, it painful. I don't know how to optionally add criteria into the query. Here is my "concept" query, which, of course, does not work:

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
                         };

How can I do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怪我入戏太深 2024-10-28 12:58:24

您可以尝试利用 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 使用延迟执行。现在您可以浏览并添加

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);
}

我尚未测试过的 where 子句,因此如果某些内容仍然无法正常工作,请告诉我。

Instead of creating it using the more SQL style Linq syntax (sorry I don't know the proper name for it), you could try taking advantage of the way IQueryable objects work. Basically what you can do is add where clauses where necessary, otherwise omit them. Something along these lines should work:

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
                 };

So keep in mind you haven't actually queried anything yet, because Linq uses deferred execution. Now you can go through and add where clauses

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);
}

I haven't tested this, so let me know if something isn't working right still.

左耳近心 2024-10-28 12:58:24

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

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

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

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

对其他条件重复。

First, you have to parse the text input from the user to see if it's really a number or not, and if yes, convert it to the decimal type. There is a handy method decimal.TryParse for that:

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

And then you can use this information in the query:

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

Repeat for other criteria.

傲性难收 2024-10-28 12:58:24

查看 C# in a Nutshell 书中描述的 PredicateBuilder 类。它允许您动态构建谓词以与 LINQ to SQL 和实体框架一起使用。

Take a look at the PredicateBuilder class described in the C# in a Nutshell book(s). It allows you to dynamically build a predicate to use with LINQ to SQL and Entity Framework.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文