如何将数组传递给执行存储命令?

Posted

技术标签:

【中文标题】如何将数组传递给执行存储命令?【英文标题】:how can I pass an array to a execute store command? 【发布时间】:2012-10-21 14:19:54 【问题描述】:

如何将用逗号分隔的整数数组传递给实体中的ExecuteStoreCommand 作为参数 我无法执行此操作:

this.ObjectContext.ExecuteStoreCommand("INSERT INTO SurveyPatientListMrns 
  (UserData, MrnId) SELECT DISTINCT '0' , MrnId 
FROM PatientVisits WHERE (FacilityId = 1)
AND (UnitId IN (2))", userData, facilityId, (string.Join(",", unitIds)));

这里(string.Join(",", unitIds)) 是一个字符串,由于逗号,我不能将它转换为整数。那我怎么传参数呢?

仅供参考,unitIds 是一个整数数组

【问题讨论】:

【参考方案1】:

虽然它看起来像 string.Format 操作,但 ExecuteStoreCommand 正在内部构建参数化查询以提高性能并帮助保护您免受 SQL 注入攻击。 (MSDN)

当您将string.Join 作为ExecuteStoreCommand 的参数时,它不会将该结果视为IN 子句的值列表,而是恰好看起来像一个字符串。基本上它会生成一个看起来像这样的IN 子句:

(UnitId IN ('1,2,3'))

这显然不是你想要的。

在传递ExecuteStoreCommand 之前,您必须使用string.Join-ed 列表uinitIds 构建SQL 命令:

string query = @"INSERT INTO SurveyPatientListMrns  (UserData, MrnId) 
    SELECT DISTINCT '0' , MrnId 
    FROM PatientVisits WHERE (FacilityId = 1) AND 
    (UnitId IN (" + string.Join(",", unitIds) + "))";
this.ObjectContext.ExecuteStoreCommand(query, userData, facilityId);

通常应该避免动态构建 SQL 查询,因为可能存在 SQL 注入攻击,但在这种情况下,您知道 unitIds 是一个整数列表,因此您应该没问题。

【讨论】:

【参考方案2】:

与答案相同的方法,只是演示使用强类型结果集。

void Main()

    int[] operationIds =  1000, 1001 ;
    var result = ObjectContext.ExecuteStoreQuery<EncyptedPatientInfoDataContract>(
                        $@"SELECT OperationId, Name, OfficialId, IsPatientEncrypted FROM Patient WHERE OperationId IN (string.Join(",", operationIds))");
                        result.Dump();

Dump 方法是 Linqpad 中的一种方法。 Linqpad 5 中工作示例的屏幕截图:

正如公认的答案所说:

针对您构建 IN 子句的商店构建查询字符串 使用例如 string.Join 来构建逗号分隔的字符串值数组 使用 ExecuteStoreQuery 时,如果您使用 SELECT 项目,则可以将数据转换为您选择的强类型实体 - 只要其属性和相应的属性类型与数据库内容匹配,以便 Entity Framework 可以成功地将内容具体化为您用作通用参数的 POCO 对象。

【讨论】:

以上是关于如何将数组传递给执行存储命令?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以通过命令行将 vbscript 数组传递给 C++ exe?

如何给SQLSERVER存储过程传递数组参数

如何将值的“数组”传递给我的存储过程?

如何传递文件中包含的命令行参数并保留该文件的名称?

在 laravel 中,如何将多维数组作为 artisan 命令的选项传递?

如何将2D数组作为参数从C#传递给python