Вопрос

I've got a Telerik RadGrid with the following Select query in the data source it's bound to:

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

The RadGrid has filterable columns, and the code behind is storing the filters in Session so that when you navigate back to the page, the filters are maintained. The code behind effectively tacks on a WHERE clause to the Select query:

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

The full result of the query (when not filtered) is upwards of 4,000 rows, so the grid is also paginated.

The Problem

I need to add a checkbox to the page which will filter the grid to only display groups with no contacts stored in the DB. I've added a checkbox to the page already, and its state is being saved in Session along with the filter information (and some other fields on the page). That's all working fine.

Getting the grid to correctly filter based on that checkbox, however, is proving difficult. The contacts are stored in the Contacts table, which has a column ClientID to match Client.ClientID/Group.ClientID, although there aren't any foreign keys involved. (Client, Carrier, and Plan are actually mirrors of tables on a remote database which gets updated regularly, so changes to them would be overwritten even if I had permission to do so.)

Testing queries in Microsoft SQL Server Management Studio, the following gets me the information I need:

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

However, if I modify the RadGrid's data source to reflect this query and modify the FilterExpression in the code behind to include AND [Contacts]=0 (or empty string when unchecked) and add the FilterExpression code above to my _CheckedChanged callback method, the filter results are incorrect while the checkbox is checked (the grid contains rows, while the DB currently contains no groups without contacts), and the grid is very slow to update with the normal filters while the checkbox is unchecked.

  1. Is there a better way to bind my grid to this set of information?
  2. What reason might there be why the query works in theory, but not in practice?
Это было полезно?

Решение

You need to use a left outer join instead of an inner join for your filter to work.

Your sub-query SELECT COUNT(*) AS Contacts, ClientID FROM Contacts GROUP BY ClientID is only going to return rows with Contacts > 0, since you are selecting from the Contacts table, and clients who have no contacts wont have their ClientID present in the table, so the GROUP BY ClientID won't find them.

Try using a LEFT OUTER JOIN and WHERE [Contacts] is null as the filter.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top