首页新闻找找看学习计划

linq 动态循环Concat的问题

0
悬赏园豆:50 [已解决问题] 解决于 2013-05-15 15:32

C#程序:

void Main()
{
int[] r={4,5,11};

var query = from a in Sales where 1==0 select a.ID;
foreach(int n in r)
{
query = query.Concat(from a in Pig where a.ID==n select a.ID);
}

Console.Write(query);
}

 

query 生成的sql语句:

-- Region Parameters
DECLARE @p0 Int = 0
DECLARE @p1 Int = 11
DECLARE @p2 Int = 11
DECLARE @p3 Int = 11
-- EndRegion
SELECT [t6].[ID]
FROM (
SELECT [t4].[ID]
FROM (
SELECT [t2].[ID]
FROM (
SELECT [t0].[ID]
FROM [Sales] AS [t0]
WHERE @p0 = 1
UNION ALL
SELECT [t1].[ID]
FROM [Pig] AS [t1]
WHERE [t1].[ID] = @p1
) AS [t2]
UNION ALL
SELECT [t3].[ID]
FROM [Pig] AS [t3]
WHERE [t3].[ID] = @p2
) AS [t4]
UNION ALL
SELECT [t5].[ID]
FROM [Pig] AS [t5]
WHERE [t5].[ID] = @p3
) AS [t6]

 

正确的结果应该是@p1=4,@p2=5,@p3=11,而实际生成的sql为什么都是11?

其实我原本的目的是:

var query = from a in Sales where a.ID==4 || a.ID==5 || a.ID==11 select a.ID;

但用or语句导致效率很低,所以想改为union all方式,但生成的sql不正确.

settan的主页 settan | 初学一级 | 园豆:154
提问于:2013-05-15 12:15
< >
分享
最佳答案
1
foreach(int n in r)
{
    var x = n;
    query = query.Concat(from a in Pig where a.ID==x select a.ID);
}

foreach开始加一句就可以了。这个是lambda表达式闭包引起的。

收获园豆:50
水牛刀刀 | 大侠五级 |园豆:6350 | 2013-05-15 14:07

果然是这样! 非常感谢!

不过类似这样的sql语句感觉效率真的好低,不知怎么优化?

其实就是对同一个字段或条件判断.

select * from dbo.Pig as t where t.ID=1 or t.ID=2 or t.ID=3 ...

settan | 园豆:154 (初学一级) | 2013-05-15 15:17

@settan: 用 Queryable.Contains 方法,(如果我没记错的话)会被翻译成IN查询.

var ids = new int[] { 4, 5, 11 };
query = from a in Sales where ids.Contains(a.ID);
水牛刀刀 | 园豆:6350 (大侠五级) | 2013-05-15 15:29

@水牛刀刀: 测试了一下:

1.用Contains,生成in语句的sql:

var query = from a in Pig where r.Contains(a.TypeID) select a;

2.用or,生成or语句的sql:

var query = from a in Pig where a.TypeID==4 || a.TypeID==5 || a.TypeID==11 select a;

3.用Concat,生成union all 语句的sql:

int[] r={4,5,11};
var query = from a in Pig where 1==0 select a;
foreach(int n in r)
{
int x = n;
query = query.Concat(from a in Pig where a.TypeID==x select a);
}

 

以上三种方式,第一种和第二种方式效率差不多,都需要14s左右,

还是第三种方式效率高一些,只要4s左右.但感觉还是达不到期望的效率.

难道就没有更好的办法了吗?

settan | 园豆:154 (初学一级) | 2013-05-15 17:45

@settan: 14秒?开玩笑吧...就这么个简单的select要这么久,你是在侮辱微软的程序员啊.. 你就是根据id select记录出来?还是你这个问题是简化过的.

水牛刀刀 | 园豆:6350 (大侠五级) | 2013-05-15 17:48

@水牛刀刀: 不是根据ID,而是根据TypeID,而且查询对象Pig是个视图

settan | 园豆:154 (初学一级) | 2013-05-15 17:52

@settan: UNION确实可能比OR快(同理IN),看这里:http://stackoverflow.com/questions/5639710/union-all-vs-or-condition-in-sql-server-query

水牛刀刀 | 园豆:6350 (大侠五级) | 2013-05-15 17:55

@settan: 猜测是根据TypeID去获取到记录是很快的,因此多个这样的操作UNION起来也比较快。而OR破坏了一些“快的因素”,例如视图索引。同理IN。

水牛刀刀 | 园豆:6350 (大侠五级) | 2013-05-15 17:58
其他回答(1)
0

你这叫效率高? 完全不敢认同

丫的 | 园豆:1575 (小虾三级) | 2013-05-15 13:11

效率的确很低,可是应该怎么优化呢?

支持(0) 反对(0) settan | 园豆:154 (初学一级) | 2013-05-15 15:23
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册