NSPredicate 过滤 coredata 中的继承对象

NSPredicate filter inherited object in coredata

问题

大家好,我是这样设计我的CoreData的(我会写的尽量简单,而我的真实数据要复杂得多):

Product (Abstract)
   - NSString *productName
   - NSDecimalNumber *productPrice
   - NSString *productType

ProductComplex : Product
   - (NSSet <ProductSimple *> *)childProducts

ProductSimple : Product
   - (ProductComplex *)parentProduct

所以基本上,Product 是一个抽象类型,它有 2 个属性:名称和价格。 Product 有 2 个继承:

  1. ProductComplex: 这可能有很多子产品。
  2. ProductSimple:这可能是复杂产品的子产品,也可能不是。

然后,我有一个列表来显示所有产品(当然是摘要 Product)。现在我想创建一个谓词来过滤具有这些条件的 Product 列表:

  1. 只显示 ProductComplex 其中有 childProducts (childProducts.@count > 0).
  2. 只显示没有任何 parentProduct (parentProduct = nil) 的 ProductSimple

我的尝试

我正在使用 NSFetchResultController,其中 entityName 是 Product。我试过创建一个谓词:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"childProducts.@count > 0 OR parentProduct = nil"];

这会在执行获取 fetchResultController 时导致崩溃:

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

这是简化的崩溃原因:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't have a non-relationship collection element in a subquerySUBQUERY(childProducts, $child, $child.productPrice > "0")'

请帮我创建一个过滤器。

编辑 1

我什至试过像下面这个谓词这样的东西来确保它有关系,但这也不起作用。

[NSPredicate predicateWithFormat:@"productType = 'complex' AND childProducts.@count > 0"]

编辑 2

开启SQL调试模式后,发现fetch生成的SQL。阅读那个 SQL 查询,我认为不可能按照我的要求做:( 仍然希望得到答案。

不幸的是,这是不可能的。尽量避免在数据库中使用 inheritance。您可以使用外键将 ProductComplexProductSimple 作为 table 引用基础产品 table。它允许避免继承并提高性能。