Dapper를 사용하여 동적 테이블 이름을 어떻게 sanitise합니까?

c# dapper sql

문제

Dapper를 처음 사용하고 제공된 스키마와 테이블에서 가져올 쿼리를 작성하고 동적 순서 지정 및 필터링을 사용합니다.

Dapper는 동적 매개 변수를 매우 간단하게 만들지 만, 순서와 where 절에서 테이블을 사용하여이 작업을 수행하는 방법을 잘 모르겠습니다. 아래에 제 방법이 있습니다. SQL 주입과 관련된 문제를 봅니다.

    public GridData GetGridData(string schema, string table, TableDataParameters tableDataParameters)
    {
        using (var dbConnection = VarConnection)
        {
            dbConnection.Open();

            if (!this.TableExists(dbConnection, schema, table))
            {
                throw new ItemNotFoundException($"Could not locate table {schema}.{table}.");
            }

            string orderyByClause = string.Join(",", tableDataParameters.SortModel.Select(s => $"[{s.ColId}] {(s.Sort.ToLower() == "asc" ? "asc" : "desc")}"));

            var parameters = new DynamicParameters();

            string whereClause; 
            if (tableDataParameters.FilterModel == null || !tableDataParameters.FilterModel.Any())
            {
                whereClause = "1=1";
            }
            else
            {
                whereClause = string.Join(" AND ", tableDataParameters.FilterModel.Select((fm, i) =>
                {
                    string whereParam = $"whereParam{i}";
                    parameters.Add(whereParam, fm.Filter);

                    if (fm.Operation == "startsWith")
                    {
                        return $"[{fm.Column}] LIKE @{whereParam} + '%'";
                    }
                    throw new InvalidOperationException($"Unsupported filter operation '{fm.Operation}'");
                }));
            }

            var query = $"SELECT COUNT(1) [total] " +
                        $"FROM [{schema}].[{table}] " +
                        $"WHERE {whereClause} " +
                        $"SELECT * " +
                        $"FROM [{schema}].[{table}] " +
                        $"WHERE {whereClause} " +
                        $"ORDER BY {orderyByClause} " + 
                        $"OFFSET {tableDataParameters.StartIndex.Value} ROWS " +
                        $"FETCH NEXT {tableDataParameters.StopIndex.Value - tableDataParameters.StartIndex.Value} ROWS ONLY";
            int total = 0;
            using (var reader = dbConnection.ExecuteReader(query, parameters)) 
            {
                //  First batch, it's the count
                if (reader.Read())
                {
                    total = reader.GetInt32(0);
                }

                var gridColumns = new List<GridColumn>();
                var gridRows = new List<string[]>();
                if (reader.NextResult() && reader.Read())
                {
                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        string key = reader.GetName(i);
                        gridColumns.Add(new GridColumn(key, key, null, ""));
                    }

                    var items = new object[reader.FieldCount];
                    reader.GetValues(items);
                    gridRows.Add(items.Select(i => i.ToString()).ToArray());
                }

                while (reader.Read())
                {
                    var items = new object[reader.FieldCount];
                    reader.GetValues(items);
                    gridRows.Add(items.Select(i => i.ToString()).ToArray());
                }

                return new GridData(tableDataParameters.StartIndex.Value, tableDataParameters.StopIndex.Value, total, gridRows.Count(), gridColumns.ToArray(), gridRows.ToArray());
            }
        }
    }

이 경우 DbCommandBuilder.QuoteIdentifier, https://msdn.microsoft.com/en-us/library/system.data.common.dbcommandbuilder.quoteidentifier (v= vs.110).aspx와 같은 것을 사용해야합니까? 그것은 여기에서 그렇게 많이 도움이되는 것처럼 보이지 않습니다.

감사!

인기 답변

동적 매개 변수는 모순입니다! Dapper는 매개 변수를 쉽게 만들지 만 표 및 열 이름을 매개 변수화 할 수는 없습니다. 이는 SQL의 제한 사항이며 대담하지는 않습니다. 정말로 이것을하고 싶다면, 동적 인 SQL과 문자열 메소드를 사용해야하며, SQL 인젝션에 관해서는 스스로 결정해야합니다.

이 일을하지 않으면 더 행복 해지고 오래 살 수 있습니다. 그것은 단지 나쁜 길입니다. 당신은 많은 가치를 추가하지 않고 잠재적으로 많은 문제와 한계를 초래합니다.

마치 데이터베이스를 탐색 할 앱을 작성하는 것처럼 보입니다. 좋은 도구가 이미 존재합니다!



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