我有一个带有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
};
我该怎么做?
答案 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一起使用。