简体   繁体   English

如何在 C# 中将字符串列表作为 SQL 参数传递

[英]How do i pass a list of strings as a SQL Parameter in C#

I am using entity framework.我正在使用实体框架。 I have been told the suggested way of executing direct sql is to use parameters instead of directly inserting values into the query string.有人告诉我执行直接 sql 的建议方法是使用参数而不是直接将值插入查询字符串中。 i tried making invidual sql parameters and realize there is a 2100 parameter limitation (i had 8000 string params in the list)... I can get this working by passing the value directly to the mySQLQuery string, but i want to know how to passing it as a parameter to avoid sql injection attacks?我尝试制作单个 sql 参数并意识到有 2100 个参数限制(我在列表中有 8000 个字符串参数)...我可以通过将值直接传递给 mySQLQuery 字符串来使其工作,但我想知道如何传递它作为参数来避免sql注入攻击? I tried the code below我试过下面的代码

var mySQLQueryString = "...WHERE DataID IN (@mySQLVariable)";
List<string> dataList = new List<string>();
SqlParameter param = new SqlParameter("@mySQLVariable", string.Join(",", dataList.ToArray()));
return context.Database.SqlQuery<ConcretePOCO>(mySQLQueryString, param).ToList();

When looking at it through a profiler, the data being sent to the SQL is '1,2,3,4'...i need it to be '1', '2', '3', '4'....当通过探查器查看它时,发送到 SQL 的数据是 '1,2,3,4'...我需要它是 '1', '2', '3', '4'.. ..

how do i accomplish this while sending as a parameter?作为参数发送时如何完成此操作?

How about using Table Valued Parameters in EF :如何在 EF 中使用表值参数:

Create a new Type in SQL在 SQL 中创建一个新Type

CREATE TYPE DataIds AS TABLE  
(  
    DataID int 
) 

In your method, create a new DataTable from your list在您的方法中,从您的列表中创建一个新的DataTable

using System.Ling;
using System.Data;
// ...

var dataIds = new DataTable();  
dataIds.Columns.Add("DataID", typeof(int));

List<string> dataList = new List<string>();
// do what ever to fill your list with parameters

foreach (String item in dataList)
{
    DataRow row = dataIds.NewRow();
    row["DataID"] = item;
    table.Rows.Add(row);
}

// When fetching data
var mySQLQueryString = "...WHERE DataID IN (SELECT DataID FROM @mySQLVariable)";
SqlParameter param = new SqlParameter("@mySQLVariable", SqlDbType.Structured);  
param.Value = dataIds;  
param.TypeName = "dbo.DataIds";  
return context.Database.SqlQuery<ConcretePOCO>(mySQLQueryString, param).ToList();

Use a delimiter when passing to sql and then use STRING_SPLIT in the sql to break it up into a table.传递给 sql 时使用分隔符,然后在 sql 中使用 STRING_SPLIT 将其分解为一个表。

Example:例子:

SqlParameter param = new SqlParameter("@mySQLVariable", string.Join("**~**", dataList.ToArray()));

And then in sql do然后在 sql 中做

select value FROM STRING_SPLIT(@mySQLVariable, '~')

There are several ways I can think of to get this done.我可以想到几种方法来完成这项工作。 One possible way of doing this is just to keep the work on the server, and not in the query.一种可能的方法是将工作保留在服务器上,而不是在查询中。 Keep in mind that depending on how much data we're talking about, this might not be the fastest process.请记住,根据我们讨论的数据量,这可能不是最快的过程。 But if we're only talking about 9,000, then it should be okay.但如果我们只是谈论 9,000,那么应该没问题。

Using LINQ with Entity Framework, and if your Id's are alphanumeric, then this should work.将 LINQ 与 Entity Framework 一起使用,并且如果您的 Id 是字母数字,那么这应该可行。 Your syntax may vary based on your implementation...您的语法可能因您的实现而异...

var myResults= context.MyTable.Any(t => t.DataID.Intersect(dataList));

Now, if this ends up being too slow, then you can convert your list of ID's to a HashSet .现在,如果这最终太慢,那么您可以将您的 ID 列表转换为HashSet

 var myHashSet = new HashSet<string>(dataList);   
 var myResults = context.MyTable.Where(t => myHashSet.Overlaps(t.DataID));

(Disclaimer: I've not tested any of this. I'm going off memory.) (免责声明:我没有测试过任何这些。我正在失去记忆。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM