过滤在另一个表中没有相应条目的网格行

时间:2013-12-10 19:58:46

标签: c# asp.net sql-server telerik-grid

我的Telerik RadGrid在其绑定的数据源中有以下Select查询:

SELECT g.GroupID,
       c.ClientName,
       r.CarrierName,
       p.PlanName
  FROM Group AS g
  JOIN Client AS c 
    ON g.ClientID=c.ClientID
  JOIN Carrier AS r
    ON g.CarrierID=r.CarrierID
  JOIN Plan AS p
    ON g.PlanID=p.PlanID

RadGrid有可过滤的列,后面的代码是将过滤器存储在Session中,这样当您导航回页面时,过滤器就会被维护。后面的代码有效地解决了Select查询的WHERE子句:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        ...
        radGrid.MasterTableView.FilterExpression = string.Format("([ClientName] LIKE '%{0}%' AND [CarrierName] LIKE '%{1}%' AND [PlanName] LIKE '%{2}%')",
                                                                 clientName, carrierName, planName);
        ...
        radGrid.Rebind();
        ...
    }
}

查询的完整结果(未过滤时)超过4,000行,因此网格也是分页的。

问题

我需要在页面中添加一个复选框,它将过滤网格,仅显示DB中没有存储联系人的组。我已经在页面中添加了一个复选框,其状态与过滤器信息(以及页面上的其他一些字段)一起保存在Session中。这一切都很好。

然而,基于该复选框使网格正确过滤是很困难的。联系人存储在Contacts表中,该表有ClientID列以匹配Client.ClientID / Group.ClientID,但不涉及任何外键。 (ClientCarrierPlan实际上是远程数据库上的表的镜像,它们会定期更新,因此即使我有权这样做,也会覆盖对它们的更改。)

在Microsoft SQL Server Management Studio中测试查询,以下内容为我提供了所需的信息:

SELECT g.GroupID,
       c.ClientName,
       r.CarrierName,
       p.PlanName,
       con.Contacts
  FROM Group AS g
  JOIN Client AS c 
    ON g.ClientID=c.ClientID
  JOIN Carrier AS r 
    ON g.CarrierID=r.CarrierID
  JOIN Plan AS p 
    ON g.PlanID=p.PlanID
  INNER JOIN
  (
    SELECT COUNT(*) AS Contacts, ClientID
      FROM Contacts
      GROUP BY ClientID
  ) AS con
    ON g.ClientID=con.ClientID

但是,如果我修改RadGrid的数据源以反映此查询并修改后面代码中的FilterExpression以包含AND [Contacts]=0(或未选中时为空字符串)将上面的FilterExpression代码添加到我的_CheckedChanged回调方法中,选中复选框时过滤结果不正确(网格包含行,而数据库当前不包含没有联系人的组) ),并且在未选中复选框的情况下,网格非常慢以使用普通过滤器进行更新。

  1. 有没有更好的方法将我的网格绑定到这组信息?
  2. 为什么查询在理论上有效,但在实践中却没有?

1 个答案:

答案 0 :(得分:1)

您需要使用左外连接而不是内连接才能使过滤器正常工作。

您的子查询SELECT COUNT(*) AS Contacts, ClientID FROM Contacts GROUP BY ClientID仅返回包含联系人>的行0,因为您从“联系人”表中进行选择,并且没有联系人的客户端不会在表中显示其ClientID,因此GROUP BY ClientID无法找到它们。

尝试使用LEFT OUTER JOINWHERE [Contacts] is null作为过滤器。