我有一个字符串数组(query.Tags)用于过滤值列表,每次,procces只在查询执行期间获取字符串数组的第一个值。 我尝试了几种组合但没有改变。当然,我在SQL SERVER View中测试了所有这些SQL语句。
你能告诉我我做错了吗?
public IEnumerable<ActorDto> SearchMembersInLists(ListMembersQuery query)
{
IEnumerable<ActorDto> result = null;
var sql = @"select DISTINCT t.ActorId,
a.Id, a.TypeId, a.Name, a.Identifier
FROM [ActorTag] t
INNER JOIN [Actor] a ON t.ActorId = a.Id
where t.Name IN @tags
";
using (var cnx = DbConnectionFactory.GetDefault().GetConnection())
{
cnx.Open();
var query_result = cnx.QueryMultiple(sql, new { query.Tags});
result = query_result.Read<ActorDto>();
}
return result;
}
原始代码就是这样,我只是想尽可能简化
public IEnumerable<ActorDto> SearchMembersInLists(ListMembersQuery query)
{
IEnumerable<ActorDto> result = null;
var sql = @"
SELECT DISTINCT a.Id, a.TypeId, a.Name, a.Identifier,a.Description, a.Email, a.PictureUrl, a.DisplayName --Actor
FROM [RoleMember] lm
INNER JOIN [Actor] a ON lm.ActorId = a.Id
WHERE {tag_filter} {lists_filter}
ORDER BY a.DisplayName DESC OFFSET @pageIndex ROWS FETCH NEXT @pageSize ROWS ONLY
";
bool has_tags = true;
bool has_lists = true;
if (query.Tags != null && query.Tags.Any())
{
sql = sql.Replace("{tag_filter}", "a.Id IN (SELECT t.ActorId FROM [ActorTag] t WHERE t.Name IN @tags)");
has_tags = true;
}
else
{
sql = sql.Replace("{tag_filter}", "");
has_tags = false;
}
if (query.Lists != null && query.Lists.Any())
{
if (has_tags)
{
sql = sql.Replace("{lists_filter}", "AND lm.RoleId IN @lists");
}
else
{
sql = sql.Replace("{lists_filter}", "lm.RoleId IN @lists");
}
has_lists = true;
}
else
{
sql = sql.Replace("{lists_filter}", "");
has_lists = false;
}
if (!has_tags && !has_lists){
sql = sql.Replace("WHERE", "");
}
var values = new
{
lists = query.Lists,
tags = query.Tags,
pageIndex = query.PageIndex * query.PageSizeOrDefault,
pageSize = query.PageSizeOrDefault
};
using (var cnx = DbConnectionFactory.GetDefault().GetConnection())
{
cnx.Open();
result = cnx.Query<ActorDto>(sql, values);
}
return result;
}
答案 0 :(得分:1)
显示的代码没有任何问题,假设您使用的是最新版本的dapper。下面显示了一个类似的示例(可以在控制台exe等中运行)。请检查您的数据是否符合预期。
请注意;查询代码实际上可以显着简化,但我希望尽可能保持与您的示例类似。简单的替代方案是:
public static IEnumerable<ActorDto> SearchMembersInLists(ListMembersQuery query)
{
using (var cnx = GetConnection())
{
return cnx.Query<ActorDto>(
@"select Id, Name from FooActors where Name IN @Tags", new { query.Tags });
}
}
具有更复杂查询布局的完整程序如下所示。输出是:
2: Barney
4: Betty
using Dapper;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
class Program
{
static void Main()
{
// reset and populate
using (var conn = GetConnection())
{
conn.Open();
try { conn.Execute(@"drop table FooActors;"); } catch { }
conn.Execute(@"create table FooActors (
Id int not null primary key identity(1,1),
Name nvarchar(50) not null);");
conn.Execute(@"insert FooActors(Name) values(@Name);", new[]
{
new { Name = "Fred" },
new { Name = "Barney" },
new { Name = "Wilma" },
new { Name = "Betty" },
});
}
// run a demo query
var tags = new[] { "Barney", "Betty" };
var query = new ListMembersQuery { Tags = tags };
var actors = SearchMembersInLists(query);
foreach(var actor in actors)
{
Console.WriteLine("{0}: {1}", actor.Id, actor.Name);
}
}
public static IDbConnection GetConnection()
{
return new SqlConnection(
@"Initial Catalog=master;Data Source=.;Integrated Security=SSPI;");
}
public class ActorDto
{
public int Id { get; set; }
public string Name { get; set; }
}
public class ListMembersQuery
{
public string[] Tags { get; set; }
}
public static IEnumerable<ActorDto> SearchMembersInLists(ListMembersQuery query)
{
IEnumerable<ActorDto> result = null;
const string sql = @"select Id, Name from FooActors where Name IN @Tags";
using (var cnx = GetConnection())
{
cnx.Open();
var query_result = cnx.QueryMultiple(sql, new { query.Tags });
result = query_result.Read<ActorDto>();
}
return result;
}
}