NSComparisonPredicate 用于空对多关系
Posted
技术标签:
【中文标题】NSComparisonPredicate 用于空对多关系【英文标题】:NSComparisonPredicate for empty to-many relationship 【发布时间】:2013-09-15 02:33:03 【问题描述】:我在 Core Data 中的两个实体(EntityA 和 EntityB)之间存在多对多关系,我正在尝试通过删除不再与任何实例有任何关系的 EntityB 实例来定期清理数据库实体A。我正在使用 Mogenerator 创建 .m 和 .h 文件,这允许我以我的方式引用属性/关系名称。
NSPredicate *noRelationPredicate = [NSComparisonPredicate predicateWithLeftExpression:[NSExpression expressionWithFormat:@"%K", EntityBRelationships.relationshipNameForEntityA] rightExpression:[NSExpression expressionWithFormat:@"nil"] modifier:NSDirectPredicateModifier type:NSEqualToPredicateOperatorType options:0];
但是,我在执行 fetch 时遇到以下错误:'NSInvalidArgumentException',原因:'to-many key not allowed here'
我更喜欢使用类方法 NSComparisonPredicate predicateWithLeftExpression:rightExpression:modifier:type:options: 创建谓词,因为我试图在创建谓词时避免使用字符串文字。
【问题讨论】:
【参考方案1】:您可以向实体 B 添加一个类别,以检查它是否可以被删除。
-(void)willSave
if (!self.aRelations.count && !self.isDeleted)
[self.managedObjectContext deleteObject:self];
(通过在单独的文件中使用类别,如果您想重新生成托管对象子类,则不会覆盖此代码。)
【讨论】:
谢谢 Mundi,我会试试这个 似乎 willSave 导致某种递归行为发生...我收到“无法在保存前处理挂起的更改。 100 次尝试后上下文仍然很脏。通常,这种递归污染是由错误的验证方法、-willSave 或通知处理程序引起的。' 实际上我通过检查是否 !self.deleted 来避免这个错误。但有时,我似乎过早地删除了 self,因为我的增量存储稍后会抛出此错误:'NSInvalidArgumentException',原因:'*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil' 你也可以试试-didSave
。是的,我忘了包含 isDeleted 检查。【参考方案2】:
在定义关系时,可以指定 CoreData 对“孤立”实例的处理方式。请参阅此处的“关系删除规则”:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdRelationships.html#//apple_ref/doc/uid/TP40001857-SW1
特别是,您可以使用“级联”来为您处理删除。来自文档:
级联
删除关系目的地的对象。为了 例如,如果您删除一个部门,则解雇该部门的所有员工 同一部门。
【讨论】:
我之前尝试过使用级联,但是由于它是多对多的关系,所以它似乎没有像我预期的那样工作。也许我误解了它是如何工作的,但是我无法根据其他因素阻止删除......最终删除了我不想被删除的项目。以上是关于NSComparisonPredicate 用于空对多关系的主要内容,如果未能解决你的问题,请参考以下文章
Flutter Bloc Test:空值检查运算符用于空值(空安全)
Navigator.pushReplacement 提供用于空值的空检查运算符。这次是 - 状态