使用where子句中的键值对列表选择语句
本文关键字:列表 选择 语句 键值对 where 子句 使用 | 更新日期: 2023-09-27 18:26:56
我想找到一种使用Entity框架来实现这一点的方法,但我会接受sql来实现。给定一个键值对列表,有没有方法从table.colA=item.key和table.colB=item.value的表中选择所有行?
例如,给定以下表格数据:
colA colB colC
------------------
1 3 abc
1 3 def
5 6 abc
5 8 def
9 10 abc
9 3 def
以及以下列表:
[{1, 3}, {5, 6}, {9, 3}]
我返回了以下行:
colA colB colC
------------------
1 3 abc
1 3 def
5 6 abc
9 3 def
因此,我需要的结果查询受到以下因素的影响:
select * from tableData
where
(colA = 1 AND colB = 3) OR
(colA = 5 AND colB = 6) OR
(colA = 9 AND colB = 3)
最干净的方法是使用表值参数
然后,您可以对表参数和目标表进行内部联接,以从表中检索行。
有关使用表值参数的详细信息,请参阅MSDN的这篇文章。
如果您使用的是2008年以前的SQL版本,或者不想使用表值参数,那么您可以将这两个值连接在一起,并使用IN子句,类似于:
SELECT * FROM MyTable WHERE CAST(ColA as varchar(10)) + '|' + CAST(ColB as varchar(10)) IN ('1|3', '5|6', '9|3')
试试这个Sqlfiddle演示http://sqlfiddle.com/#!3/ff9728/5
;WITH split_names
AS (SELECT CONVERT(XML, '<cols><col>'
+ Replace( Replace(split.a.value('.','VARCHAR(100)'),
'}',
''),
',', '</col><col>')
+ '</col></cols>') AS xmlname
FROM (SELECT Cast ('<M>'
+ Replace(Replace(Replace( Replace(
'[{1, 3}, {5, 6}, {9, 3}]', ']'
, ''),
'[', ''
), '{', ''), '},', '</M><M>')
+ '</M>' AS XML) AS Data) AS A
CROSS apply data.nodes ('/M') AS Split(a))
SELECT colA,colB,colC
FROM <tablename> t
JOIN (SELECT xmlname.value('/cols[1]/col[1]', 'int') AS col1,
xmlname.value('/cols[1]/col[2]', 'int') AS col2
FROM split_names) a
ON t.cola = a.col1
AND t.colb = a.col2
您可以使用联接:
var input = new List<KeyValuePair<int, int>>
{
new KeyValuePair<int, int>(1, 3),
new KeyValuePair<int, int>(5, 6),
new KeyValuePair<int, int>(9, 3)
};
var results = from s in db.Source
join i in input on new { s.colA, s.colB } equals new { colA = i.Key, colB = i.Value }
select new { s.colA, s.colB, s.colC };
或者你可以用Contains()
:(切换到Tuple
而不是KeyValuePair
,只是为了好玩!)
var input = new List<Tuple<int, int>>
{
new Tuple<int, int>(1, 3),
new Tuple<int, int>(5, 6),
new Tuple<int, int>(9, 3)
};
var results = from s in source
where input.Contains(new Tuple<int, int>(s.colA, s.colB))
select s;
如果由于实体框架的原因,您正在与此作斗争,那么这可能会起到相反的作用。它将键值对转换为单个字符串,由任意字符(在本例中为:
)分隔:
var input = new List<KeyValuePair<int, int>>
{
new KeyValuePair<int, int>(1, 3),
new KeyValuePair<int, int>(5, 6),
new KeyValuePair<int, int>(9, 3)
};
//Combine the two values to be searched into a single one
var parsedInput = input.Select(i => i.Key + ":" + i.Value);
var results = from s in source
where parsedInput.Contains(s.colA + ":" + s.colB)
select s;