关于级联表的SQL查询

时间:2015-04-15 14:34:20

标签: c# sql-server linq entity-framework

首先,我使用Linq和Entity Framework来创建我的查询。

我有6张桌子,它们都以层叠的方式相互依赖。 因此,表中的数据布局如下所示:

 Table 1: Id , Name
 Table 2: Id , Table1Id, Name
 Table 3: Id , Table2Id, Name 
 ...

现在我需要创建一个查询,其中所有这些结果都已连接并表示级联但我还需要将结果保存在子元素所在的位置。我不知道这是否可以理解,所以这里有一个例子:

Table 1:
1     Item1
2     Item2
3     Item3

Table 2:
1     1    Item1
2     1    Item2
3     2    Item3

Table 3:
1     1    Item1
2     3    Item2

Expected Queryresult:
Level1Id     Level1Name     Level2Id     Level2Name     Level3Id     Level3Name
________________________________________________________________________________
1            Item1          
1            Item1          1           Item1
1            Item1          1           Item1           1            Item1
1            Item1          2           Item2
2            Item2
2            Item2          3           Item3
2            Item2          3           Item3           2            Item2

查询结果不需要看起来像这样,但必须具有层次结构。

我已经尝试过使用left-outer-join,但这只提供了预期结果的叶子。 查询看起来像这样:

var databaseLevel =
 (from lev1 in db.Level1
  from lev2 in db.Level2.Where(x => x.Level1Id == lev1.Id).DefaultIfEmpty()
  from lev3 in db.Level3.Where(x => (x.Level2Id == lev2.Id)).DefaultIfEmpty()
  from lev4 in db.Level4.Where(x => (x.Level3Id == lev3.Id)).DefaultIfEmpty()
  from lev5 in db.Level5.Where(x => (x.Level4Id == lev4.Id)).DefaultIfEmpty()
  from lev6 in db.Level6.Where(x => (x.Level5Id == lev5.Id)).DefaultIfEmpty()
  select new { Level1 = lev1, Level2 = lev2, Level3 = lev3, Level4 = lev4, Level5 = lev5, Level6 = lev6 }).AsQueryable();

我已尝试过的第二种方法是将查询结果合并,并为未使用的Levels添加空值。

查询看起来像:

var databaseLevel =
    (from lev1 in db.Level1s select new { Level1 = lev1, Level2 = (Level2s)null, Level3 = (Level3s)null, Level4 = (Level4s)null, Level5 = (Level5s)null, Level6 = (Level6s)null })
    .Concat(from lev2 in db.Level2s select new { Level1 = lev2.Level1s, Level2 = lev2, Level3 = (Level3s)null, Level4 = (Level4s)null, Level5 = (Level5s)null, Level6 = (Level6s)null })
    .Concat(from lev3 in db.Level3s select new { Level1 = lev3.Level2s.Level1s, Level2 = lev3.Level2s, Level3 = lev3, Level4 = (Level4s)null, Level5 = (Level5s)null, Level6 = (Level6s)null })
    .Concat(from lev4 in db.Level4s select new { Level1 = lev4.Level3s.Level2s.Level1s, Level2 = lev4.Level3s.Level2s, Level3 = lev4.Level3s, Level4 = lev4, Level5 = (Level5s)null, Level6 = (Level6s)null })
    .Concat(from lev5 in db.Level5s select new { Level1 = lev5.Level4s.Level3s.Level2s.Level1s, Level2 = lev5.Level4s.Level3s.Level2s, Level3 = lev5.Level4s.Level3s, Level4 = lev5.Level4s, Level5 = lev5, Level6 = (Level6s)null })
    .Concat(from lev6 in db.Level6s select new { Level1 = lev6.Level5s.Level4s.Level3s.Level2s.Level1s, Level2 = lev6.Level5s.Level4s.Level3s.Level2s, Level3 = lev6.Level5s.Level4s.Level3s, Level4 = lev6.Level5s.Level4s, Level5 = lev6.Level5s, Level6 = lev6 })
     .AsQueryable(); 

此查询工作正常,但性能非常差。 现在我没有任何其他想法如何创建我的查询...

有人可以给我一个提示吗?

1 个答案:

答案 0 :(得分:0)

对于我创建的表(如果您提供带有数据的插入,我会将其转换为您想要的密钥是汇总和分组功能):

create table c1 (c1 varchar(20), c2 varchar(20), c3 varchar(20))

select case when (grouping(c1) =1 ) then ' ' else isnull(c1,' ') end as c1,
 case when (grouping(c2)=2) then ' ' else isnull(c2,' ') end as c2,
 case when (GROUPING(c3)=3) then ' ' else isnull(c3,' ') end as c3
    from c1 
group by c1,c2,c3 with rollup
order by c1,c2,c3 




Canada       
Canada  CT   
Canada  CT  Wilton
Canada  North    
Canada  North   Vancouver
Us       
Us  CT   
Us  CT  Wilton
Us  NJ   
Us  NJ  Brooklyn
Us  NJ  teaneck
Us  NY   
Us  NY  Brooklyn
Us  NY  NY

产生了你想要的东西。

您的加入必须是这样的:

select * from 
table1 inner join table2 on [id]=table1id
 inner join table3 on table2id=table2.id