我想找到一种使用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)
答案 0 :(得分:0)
您可以使用加入:
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;
答案 1 :(得分:0)
最干净的方法是使用表格值参数 然后你可以在table参数和目标表上进行内连接,以从表中检索行。
有关使用表值参数的详细信息,请参阅this 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')
答案 2 :(得分:0)
试试这个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