2

I am loading all first level/root units into my Treeview.

Whether a unit has children or not determines whether the treeview shows "+".

In order to make this symbol available on the left hand side of the unit name I need to check on my SQL server whether each unit has children or not. I do not need the count, just whether children exist is enough.

I even know there was once a very good rated SO solution about the same topic, but I could not find this solution with the search.

I would appreciate the solution or any helpful links :)

Code follows:

public IEnumerable<Unit> GetRootUnits(int templateId)
{
    List<Unit> units = new List<Unit>();

    using (var con = new SqlConnection(_connectionString))
    using (var cmd = new SqlCommand())
    {
        cmd.Connection = con;
        cmd.CommandText = "SELECT UnitId, ParentId, Name, TemplateId, HasChildren FROM Unit WHERE ParentId Is NULL AND TemplateId = @TemplateId";
        con.Open();

        var p1 = new SqlParameter("@TemplateId", templateId);
        cmd.Parameters.Add(p1);

        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                Unit unit = new Unit();
                unit.Id = Convert.ToInt32(reader["UnitId"]);
                unit.Name = reader["Name"].ToString();
                unit.TemplateId = Convert.ToInt32(reader["TemplateId"]);
                unit.ParentId = null;
                unit.IsLazy = Convert.ToBoolean(reader["HasChildren"]);
                units.Add(unit);
            }
        }
    }        
    return units;
}

Update:

I tried this:

   SELECT Unit.UnitId, Unit.ParentId, Unit.Name, Unit.TemplateId,
      case when Exists(select null from Unit u2 where u2.ParentID = unit.UnitID)
     then 1
     else 0
     end as HasChildren
  FROM [ITMS].[dbo].[Unit]

My test data:

1   NULL    unitroot1   1
2   NULL    unitroot2   1
3   NULL    unitroot3   1
4   NULL    unitroot4   1
5   NULL    unitroot5   1
6   NULL    unitroot6   1
7   NULL    unitroot7ffds fasddfasfds fsdadsffdsa fasdadsf  1
8   NULL    flfsaklfakl 1
9   NULL    flk43053094 1
10  NULL    sdaklr0340  1
11  NULL    3405303 1
12  NULL    543ß5ß343   1
13  NULL    54ß53ß534   1
14  NULL    45o345jo435jo   1
15  NULL    as435l5l54lk5   1
16  NULL    543095454j34    1
17  NULL    45354   1
18  NULL    kl  1
19  NULL    43534   1
20  NULL    5435    1
21  NULL    1   1
22  NULL    12  1
23  NULL    bla 1
24  7   childrenOfUnitRoot7 this is a scrolling test    1
25  24  blubb   1
4

1 に答える 1

2

親に子がいるかどうかの情報を取得し、その情報をHasChildren列に返す場合は、exists を使用できます。

case when exists (select null from Unit u2 where u2.ParentID = unit.UnitID)
     then 1
     else 0
     end as HasChildren

または、 applyに行くこともできます:

SELECT Unit.UnitId, Unit.ParentId, Unit.Name, Unit.TemplateId, 
       isnull(c.HasChildren, 0) HasChildren
  FROM Unit 
 -- Get first child record. Returns null record if not found.
 OUTER APPLY
 (
   select top 1
          1 as HasChildren
     from Unit u2
    where u2.ParentID = Unit.UnitID
 ) c
 WHERE Unit.ParentId Is NULL 
   AND Unit.TemplateId = @TemplateId

3 番目のオプションは、それ自体Unitの派生バージョンに参加することです。Unit

SELECT Unit.UnitId, Unit.ParentId, Unit.Name, Unit.TemplateId, 
    -- If c.ParentID is not null we know that there must be
    -- at least one child for this UnitID
       case when c.ParentID is not null then 1 else 0 end HasChildren
  FROM Unit 
  LEFT JOIN
  (
    select distinct ParentID
      from Unit
  ) c
    ON Unit.UnitID = c.ParentID
  WHERE Unit.ParentId Is NULL 
    AND Unit.TemplateId = @TemplateId

最後に、これが Sql Server 2008 の場合、HierarchyId datatypeがあります。まだ使っていないので感想は言えませんが、一見の価値ありです。

于 2012-06-04T02:34:56.090 に答える