2017-06-28 18 views
1

我试图做到这一点有填充像这样Dapper.net与数组元素的数量不详

var filter = new Filter 
{ 
    ThingID = 1, 
    Keywords = new[] { "op", "s" } 
}; 

过滤器对象,然后才能建立这样的查询:

var sb = new StringBuilder(); 
sb.AppendLine("select * from Stuff where 1=1"); 
if (filter.ThingID.HasValue) 
{ 
    sb.AppendLine(" and ThingID = @ThingID"); 
} 
if (filter.Keywords != null) 
{ 
    for (int i = 0; i < filter.Keywords.Length; i++) 
    { 
     string keyword = filter.Keywords[i]; 
     if (!string.IsNullOrWhiteSpace(keyword)) 
     { 
      sb.AppendLine(" and (Model like '%' || @Keywords" + i + " || '%')"); 
     } 
    } 
} 
var sql = sb.ToString(); 
var results = Query<Stuff>(sql, filter).ToList(); 

这工作正常,如果只是ThingID道具填充,但据我可以告诉Dapper不以任何方式作为参数提供关键字。这对于Dapper来说是可能的,还是只能在“@Keywords中的关键字”的情况下工作?

回答

2

参数需要按名称匹配;您正在添加像@Keywords17这样的参数,但没有Keywords17属性供它添加。它不解释为Keywords[17],如果这是你的意思。有平面阵列的一些自动扩展,但是这是用于扩展in @Keywords(虽然扩展本身并不特定于in)。目前没有什么能够自动帮助你的。我建议DynamicPaameters代替:

var args = new DynamicParameters(); 
args.Add("ThingID", 1); 
... 
if (!string.IsNullOrWhiteSpace(keyword)) 
{ 
    sb.AppendLine(" and (Model like '%' || @Keywords" + i + " || '%')"); 
    args.Add("Keywords" + i, keyword); 
} 
... 
var cmd = new CommandDefinition(sql, args, flags: CommandFlags.NoCache); 
var results = Query<Stuff>(cmd).AsList(); 

记在这里就结束了微妙的两个变化 - CommandFlags.NoCache将有助于避免建设大量的类似,但不同的SQL查询的条目(虽然你可能会选择支付这笔每个项目的减少成本,由你决定)。 AsList而不是ToList避免了额外的列表分配。