【问题标题】:Filtering grid rows which DON'T have corresponding entries in another table过滤在另一个表中没有对应条目的网格行
【发布时间】:2013-12-13 23:17:29
【问题描述】:

我有一个 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 中,以便当您导航回页面时,过滤器会被保留。后面的代码有效地将 WHERE 子句附加到 Select 查询中:

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 行,因此网格也是分页的。

问题

我需要在页面上添加一个复选框,该复选框将过滤网格以仅显示没有存储在数据库中的联系人的组。我已经在页面中添加了一个复选框,它的状态与过滤器信息(以及页面上的其他一些字段)一起保存在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. 查询在理论上有效但在实践中无效的原因可能是什么?

【问题讨论】:

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


    【解决方案1】:

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

    您的子查询 SELECT COUNT(*) AS Contacts, ClientID FROM Contacts GROUP BY ClientID 只会返回联系人 > 0 的行,因为您是从联系人表中选择的,并且没有联系人的客户不会在表中显示其 ClientID,因此 GROUP BY ClientID找不到他们。

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

    【讨论】:

    • /叹息。我很想在我们的系统上对此进行测试,看看这是否能解决问题……但在您发布答案之前,我们的服务器管理员进行了一些更改,而我仍然没有我的权限恢复。显然不是你的错,但仍然非常令人沮丧。
    • 这是找到我的解决方案的主要关键。其他两部分正在更改子查询中的列(ClientContact 而不是Contacts——这是我的一个错误,因为沟通和文档不畅),并在绑定到Contacts 的网格中添加另一列场地。如果没有最后一部分,则选中该框会使用整个数据集填充表格。
    猜你喜欢
    • 2021-08-02
    • 2016-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 2011-05-03
    • 1970-01-01
    相关资源
    最近更新 更多