在 NSPredicate 中结合“AND"和“OR"条件 [英] Combining 'AND' and 'OR' Condition in NSPredicate

查看:26
本文介绍了在 NSPredicate 中结合“AND"和“OR"条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

再次需要更多帮助来构建我的 NSPredicates :(

Back again needing more help with constructing my NSPredicates :(

Category
{
   name:string
   subs<-->>SubCategory
}

SubCategory
{
   name:string
   numbervalue:NSNumber
}

我想知道如何使用 ANDOR 创建谓词.

I would like to know how to create a predicate with AND and OR.

例如,我想返回名称 == "category_name" 的每个类别,该类别还有一个子类别,其数值为 "valueA" OR "valueB".

For example, I would like to return every Category with name == "category_name" that also has a subcategory with a numbervalue of "valueA" OR "valueB".

我已经尝试了我能想到的所有可能的谓词构造函数组合,但我就是无法让它工作.

I've tried every possible combination of predicate constructors I could come up with but I just cant get it to work.

这是我迄今为止最好的尝试.

This is my best attempt so far.

NSPredicate *predicate=[NSPredicate predicateWithFormat@"(name== %@) AND (ANY subs.numbervalue==%@ OR ANY subs.numbervalue==%@)", @"aname", value1, value2];

编辑 1

第二次尝试.对数值"的过滤仍然无效.

Second attempt. The filtering on the 'numbervalue' is still not working.

NSNumber valueA=[NSNumber numberWithInt:20];
NSNumber valueA=[NSNumber numberWithInt:90];
NSArray *arr=[NSArray arrayWithObject:valueA,valueB,nil];

predicate=[NSPredicate predicateWithFormat:@"(name==%@)AND(ANY subs.numbervalue IN %@)",@"aname",arr];

编辑 2

我尝试过仅按 numberValue 进行过滤,但已将名称完全忽略.

I've tried filtering just by numberValue and have left the name out alltogether.

1) 使用此方法会导致返回整个集合,即使集合中只有 1 个项目具有该值.

1) using this results in the entire set being returned even if only 1 item in the set has the value.

predicate=[NSPredicate predicateWithFormat:@"(ANY subs.numbervalue IN %@)",arr];

2) 使用这个会导致同样的问题,即使其中只有 1 个匹配,也会返回集合中的每个项目.

2) Using this results in the same problem, every item in the set being returned even if only 1 of them matches.

predicate=[NSPredicate predicateWithFormat:@"((SUBQUERY(subs, $x, $x.numbervalue == %@ or $x.numbervalue == %@).@count > 0)", value1, value2];

使用最简单的版本也会导致同样的问题......我之前没有注意到这一点.

Also using the simplest version results in the same problem.... I didnt notice this earlier.

NSPredicate *predicate=[NSPredicate predicateWithFormat@"(ANY subs.numbervalue==%@ ,valueA];

所以我想我的问题已经缩小了.

So I think I have my problem narrowed down.

类别是一个实体.子类别是一个实体.

Category is an Entity. SubCategory is an Entity.

Category 与 SubCategory 是一对多的关系,表示为 SubCategory 的 NSSet.

Category has a one to many relationship with SubCategory and is represented as an NSSet of SubCategory.

每个子类别都有一个名为 numbervalue 的属性.

Each SubCategory has an attribute named numbervalue.

编辑 3

为了测试,我有 2 个类别.两个类别都有 10 个子项,每个子项的数值为 1 -10;

To test I have 2 Categorys. Both Categories have 10 subs, each with a numbervalue of 1 -10;

使用此代码返回两个类别以及每个类别的所有 10 个子项.

Using this code both categories are returned along with all 10 subs for each.

预期的结果是返回两个类别,每个类别只有 2 个子项.

Expected result is both categories returned , each with just 2 subs.

我已经找出了我所有的对象并且数据是正确的.问题是我无法返回已过滤子项的类别.

I've traced out all my objects and the data is correct. The problem is I cant return a category that has filtered subs.

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext *context=[[DataSource sharedDataSource]managedObjectContext];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Category" inManagedObjectContext:context];
[fetchRequest setEntity:entity];

[fetchRequest setFetchBatchSize:20];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];

NSPredicate *predicate;
NSNumber *a=[NSNumber numberWithFloat:1];
NSNumber *b=[NSNumber numberWithFloat:2];
predicate=[NSPredicate predicateWithFormat:@"(SUBQUERY(subs,$x,$x.numbervalue==%@ or $x.numbervalue==%@).@count> 0)",a,b];

[fetchRequest setPredicate:predicate];
[fetchRequest setSortDescriptors:sortDescriptors];

NSError *error = nil;
[NSFetchedResultsContoller deleteCacheWithName:nil];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:@"name" cacheName:@"Master"];
aFetchedResultsController.delegate = self;

self.fetchedResultsController = aFetchedResultsController;

if (![self.fetchedResultsController performFetch:&error]) {

   NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
   abort();
}

推荐答案

我将使用 SUBQUERY 执行以下操作.

I'll do the following using a SUBQUERY.

[NSPredicate predicateWithFormat@"(name == %@) AND (SUBQUERY(subs, $x, $x.numbervalue == %@ or $x.numbervalue == %@).@count > 0)", @"aname", value1, value2];

试试看告诉我.

另一种解决方案可能是获取整个集合 subs,然后使用谓词过滤检索到的集合以检查元素是否与 value1value2.

Another solution could be to grab the whole collection subs and then filter the retrieved set with a predicate to check if elements match for value1 or value2.

希望有帮助.

编辑

如果您遵循 Eimantas 的建议,请确保创建正确的数组:

If you follow Eimantas suggestion make to sure to create the right array:

NSNumber valueA = [NSNumber numberWithInt:20];
NSNumber valueB = [NSNumber numberWithInt:90];
NSArray *arr = [NSArray arrayWithObjects:valueA, valueB, nil];

这篇关于在 NSPredicate 中结合“AND"和“OR"条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆