문자열 배열을 사용하는 IN 문에 대한 C #

arrays c# dapper

문제

나는 문자열 배열 (query.Tags) 값 목록과 각 시간, procces 목록에 대한 쿼리를 실행하는 동안 문자열 배열의 첫 번째 값을 걸릴 수 있습니다. 몇 가지 조합을 시도했지만 아무 것도 변경되지 않았습니다. 물론 SQL Server의 모든 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;        
        }

전문가 답변

귀하가 최신 버전의 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;
    }
}


아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow