简体   繁体   English

使用 IN 子句参数化 DocumentDB 查询

[英]Parameterize DocumentDB query with IN clause

I have a query somewhat like the following which I'm trying to parameterize:我有一个有点像我试图参数化的查询:

List<string> poiIDs = /*List of poi ids*/;
List<string> parameterNames = /*List of parameter names*/;

string inClause = string.Join(",", parameterNames);

string query = string.Format("SELECT c.id AS poiID, c.poiName, c.latitude, c.longitude FROM c WHERE c.clusterName = @clusterName AND c.id IN ({0}) AND c.deleted = false", inClause);

IQueryable<POI> queryResult = Client.CreateDocumentQuery<POI>(Collection.SelfLink, new SqlQuerySpec
            {
                QueryText = query,
                Parameters = new SqlParameterCollection()
                {
                    new SqlParameter("@clusterName", "POI"),
                    // How do I declare the dynamically generated parameters here
                    // as new SqlParameter()?
                }
             });

How do I declare the dynamically generated parameters as new SqlParameter() for the Parameters property of SqlQuerySpec in order to create my document query?如何将动态生成的参数声明为 SqlQuerySpec 的 Parameters 属性的 new SqlParameter() 以创建我的文档查询?

You can create dynamic parameterized query like this:您可以像这样创建动态参数化查询:

// DocumentDB query 
 // POINT TO PONDER: create the formatted query, so that after creating the   dynamic query we'll replace it with dynamically created "SQL Parameter/s"
            var queryText = @"SELECT
                                us.id,
                                us.email,           
                                us.status,
                                us.role
                            FROM user us
                            WHERE us.status = @userStatus AND us.email IN ({0})";


            // contain's list of emails  
            IList<string> emailIds = new List<string>();
            emailIds.Add("a@gmail.com");
            emailIds.Add("b@gmail.com");

            #region Prepare the query

            // simple parameter: e.g. check the user status
            var userStatus = "active";
            var sqlParameterCollection = new SqlParameterCollection { new SqlParameter("@userStatus", userStatus) };                

            // IN clause: with list of parameters:
            // first: use a list (or array) of string, to keep  the names of parameter          
            // second: loop through the list of input parameters ()
            var namedParameters = new List<string>();
            var loopIndex = 0;

            foreach (var email in emailIds)
            {
                var paramName = "@namedParam_" + loopIndex;
                namedParameters.Add(paramName);

                var newSqlParamter = new SqlParameter(paramName, email);
                sqlParameterCollection.Add(newSqlParamter);

                loopIndex++;
            }

            // now format the query, pass the list of parameter into that
            if (namedParameters.Count > 0)
                queryText = string.Format(queryText, string.Join(" , ", namedParameters));

                // after this step your query is something like this  
                // SELECT
                //                 us.id,
                //                 us.email,            
                //                 us.status,
                //                 us.role
                //             FROM user us
                //             WHERE us.status = @userStatus AND us.email IN (@namedParam_0, @namedParam_1, @namedParam_2)

            #endregion //Prepare the query

            // now inject the parameter collection object & query
            var users = Client.CreateDocumentQuery<Users>(CollectionUri, new SqlQuerySpec
            {
                QueryText = queryText,
                Parameters = sqlParameterCollection
            }).ToList();

以下为您提供了一个 SQL 查询,然后您可以在您的 DocumentDB 集合中运行,以通过其 ID 获取文档。

var query = $"SELECT * FROM p WHERE p.id IN ('{string.Join("', '", arrayOfIds)}')";

The DocumentDB SDK doesn't support parameterized IN queries. DocumentDB SDK 不支持参数化IN查询。

Judging from the SO thread in the comment above, SQL does not either.从上面评论中的SO 线程来看,SQL 也没有。 As mentioned in the other thread, you can use LINQ as a workaround.如另一个线程中所述,您可以使用 LINQ 作为解决方法。

Why not use the ArrayContains method?为什么不使用 ArrayContains 方法? Here is an example in node这是节点中的一个例子

sqlQuery = {
        query: 'SELECT * FROM t WHERE ARRAY_CONTAINS(@idList, t.id)',
        parameters: [
            {
                name: '@idList',
                value: ['id1','id2','id3'],
            },
        ],
    };

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

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