使用dapper在语句中复合

时间:2016-03-31 11:47:29

标签: sql-server dapper

假设我在sql2008中有2个表

create table table1 (
location varchar(10), 
facility varchar(10),
msgid int,
col5 varchar(20)
)

create table table2 (
msgid int,
name varchar(10),
col3 varchar(20),
col4 varchar(20)
)

insert into table1 (msgid, location, facility, col5) 
select 1, 'F1', 'L1', 'xyz'
union select 2,  'F1', L1', 'abc'
union select 3,  'F1', L1', 'abcd'
union select 4,  'F1', L2', 'abce'
union select 5,  'F2', L1', 'abcf'


insert into table2 (msgid, name, col3, col4)
select 1, 'x', 'dsd','fwefrwe'
union select 2, 'x', 'dsd1','fwefrwe1'
union select 3, 'y', 'dsd2','fwefrwe2'
union select 4, 'z', 'dsd3','fwefrwe3'
union select 5, 'a', 'dsd4','fwefrwe4'

假设我想得到以下结果

select col3,col4,col5 from table1 inner join table2 where name+'^'+facility+'^'+location in ('x^F1^L1', 'z^F1^L2')

我理解串联这样的字符串是最糟糕的事情之一,但我可以问一下,是否有更优雅的方法来优化这个语句并且可以在Dapper中使用?

非常感谢

1 个答案:

答案 0 :(得分:2)

对于事物的精巧方面,我将假设候选位置在某种列表或数组中,例如:

var locations = new[] { "x^F1^L1", "z^F1^L2" };

然后你可以使用:

var rows conn.Query<SomeType>(@"
    select col3,col4,col5 from table1 inner join table2
    where name+'^'+facility+'^'+location in @locations",
        new { locations }).AsList();

Dapper将自动为您进行扩展。

至于使其高效;你可以创建一个计算的持久索引列,假设这两个字段在同一个表上:

create table SomeTable (x nvarchar(20) not null, y nvarchar(20) not null);
alter table SomeTable add xy as x + ':' + y persisted;
create nonclustered index  SomeTable_xy on SomeTable(xy);

现在,您可以有效地查询xy,这是计算值的索引版本。

如果列在不同的表上,最好将两个分开输入并单独测试; dapper对此无法帮助你,所以你需要使用类似StringBuilderDynamicParameters(dapper)之类的东西来构建查询,但是你需要这样的东西:

where (x.ColA = @a0 and y.ColB = @b0)
or (x.ColA = @a1 and y.ColB = @b1)
...
or (x.ColA = @a42 and y.ColB = @b42)

这至少允许colAcolB上的索引有用。