Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有like and或(not and)的多个where条件_C#_Linq_Azure Cosmosdb - Fatal编程技术网

C# 具有like and或(not and)的多个where条件

C# 具有like and或(not and)的多个where条件,c#,linq,azure-cosmosdb,C#,Linq,Azure Cosmosdb,我正在查询CosmosDB,尽管LINQ/Iqueryable 我有一个方法,在输入中有一个IEnumerable,它可以有很多元素 所需的查询是 SELECT * FROM table WHERE field LIKE '%input1%' OR field1 LIKE '%input2%' 等等,通过每一个IEnumerable元素 IEnumerable<string> filterElements = GetFiltersExample(); IQuery

我正在查询CosmosDB,尽管LINQ/Iqueryable

我有一个方法,在输入中有一个IEnumerable,它可以有很多元素

所需的查询是

SELECT * FROM table WHERE field LIKE '%input1%' OR field1 LIKE '%input2%'
等等,通过每一个IEnumerable元素

IEnumerable<string> filterElements = GetFiltersExample();

        IQueryable<ResultObject> theQuery = AzureDocumentClient.CreateDocumentQuery<ResultObject>(
               collectionUri, queryOptions);

        if (filterElements.Count() > 0)
            foreach (string filterElement in filterElements)
            {
                theQuery = theQuery.Where(doc => doc.id.Contains(filterElement));
            }
如果LINQ不会自动将它们放入AND条件中,那么这应该是可行的(因为可能有一个结果中没有该字符串,所以返回空,因为它与条件不匹配)

如何在OR条件下而不是AND条件下执行此操作

我尝试了,但没有成功,因为它引发了一个异常,即无法启动Invoke方法

这就是我所做的:

var predicate = PredicateBuilder.True<ReturnObj>();
        if (elements.Count() > 0)
            foreach (string element in elements)
            {
                predicate = predicate.Or(elem => elem.id.Contains(element));
            }
你怎么能做到这一点?令人难以置信的是,我非常惊讶的是,如果您正在使用,那么您可以在
IQueryable
上使用
AsExpandable
,这样所有表达式调用都将扩展到使用实际的表达式体,而不是
Invoke(element)
。例如,如果有如下表达式:

.Where(condition1 || condition2 || condition3.....)
Expresssion<Func<int, bool>> expr = n => n == 1;
var query = (EnumerableQuery<bool>)new[] { 1 }.AsQueryable().Select(n => d.Invoke(n))   
表达式树将包含正文
n=>n==1
,而不包含
Invoke
方法

因此,在你的情况下:

IQueryable<ResultObject> theQuery = AzureDocumentClient
    .CreateDocumentQuery<ResultObject>(collectionUri, queryOptions)
    .AsExpandable()
    .Where(e => predicate.Invoke(e);

因此,不需要
AsExpandable

我使用字符串concat完成了它,因为我在项目中只有一次这个查询,我不想使用扩展库:

         StringBuilder query = new StringBuilder("SELECT * From TheCollection WHERE ");
        if (idsToCheck.Count() > 0)
            foreach (string idGuid in idsToCheck)
            {
                query.Append($" CONTAINS(TheCollection.id, '{idGuid}') OR ");
            }
        string builtQuery = query.ToString();
        builtQuery = builtQuery.Substring(0, builtQuery.Length - 4);

        IQueryable<ResultObject> Query = client.CreateDocumentQuery<ResultObject>(
               collectionUri, queryOptions);

        return Query.ToList();
StringBuilder查询=新建StringBuilder(“从集合中选择*);
如果(idsToCheck.Count()>0)
foreach(idsToCheck中的字符串idGuid)
{
Append($”包含(collection.id,{idGuid})或“);
}
string builtQuery=query.ToString();
builtQuery=builtQuery.Substring(0,builtQuery.Length-4);
IQueryable Query=client.CreateDocumentQuery(
集合URI、查询选项);
返回Query.ToList();

而且工作得很好;)

我很高兴您通过使用查询字符串找到了解决方法。我只是对你观察到的行为有一些评论

  • 在您的第一次尝试中,当您通过附加多个Where子句来构建查询时,从语义上讲,这意味着组合过滤器或相交结果。这就是为什么使用AND代替OR的原因。
    • 可以使用多个where,然后合并结果,但这远远低于使用组合查询字符串的效率
  • PredicateBuilder抱怨不支持“调用”。这是因为以下原因。在DocumentQuery LinQ表达式中,Where()调用通常会在Cosmos DB后端发送和执行之前转换为Cosmos DB查询字符串中的Where子句。如果存在非标准函数调用,则需要序列化此函数。不幸的是,序列化任何函数都不是件小事,因为函数会变得多么麻烦。其中包括PredicateBuilder或您可能拥有的自定义函数。然而,COSMOSDB确实有一个替代方案,它是用户定义函数(UDF)。(UDF)可用于在Cosmos DB后端执行自定义函数
  • 要在这种情况下使用UDF,可以使用相应OR函数的主体创建一个UDF,然后在Where()调用中使用它。一些例子可以在网站上找到

或()
创建按位Or表达式
OrElse
是有条件的或您可能正在寻找的
predicate.Or
将生成一个
|
,它
OrElse
一个
|
你可以看到我是如何为
做类似的事情的,这是一个条件,你如何将这个谓词注入到查询中?你能给我看看吗?在我分享的链接里。AndAlso接受左表达式和右表达式,并返回结果。右边是您当前的,左边是您正在注入的新的。谢谢,我宁愿使用一种更常见(也更难看)的方式,而不是使用外部库在整个项目中只执行一个查询。我期待着了解你的解释
IQueryable<ResultObject> theQuery = AzureDocumentClient
    .CreateDocumentQuery<ResultObject>(collectionUri, queryOptions)
    .AsExpandable()
    .Where(e => predicate.Invoke(e);
.Where(predicate)
         StringBuilder query = new StringBuilder("SELECT * From TheCollection WHERE ");
        if (idsToCheck.Count() > 0)
            foreach (string idGuid in idsToCheck)
            {
                query.Append($" CONTAINS(TheCollection.id, '{idGuid}') OR ");
            }
        string builtQuery = query.ToString();
        builtQuery = builtQuery.Substring(0, builtQuery.Length - 4);

        IQueryable<ResultObject> Query = client.CreateDocumentQuery<ResultObject>(
               collectionUri, queryOptions);

        return Query.ToList();