有没有办法创建谓词查询来过滤子实体?我希望能够返回一个结果集,并将过滤应用于子项。
例如我有Shape。圆形正方形是形状,我想这样做:
NSManagedObjectContext * context = [self managedObjectContext];
Circle * c = [NSEntityDescription insertNewObjectForEntityForName:@"Circle" inManagedObjectContext:context];
c.radius = @(10);
Square * s = [NSEntityDescription insertNewObjectForEntityForName:@"Square" inManagedObjectContext:context];
s.width = @(100);
s.height = @(200);
NSFetchRequest * f= [NSFetchRequest fetchRequestWithEntityName:@"Shape"];
f.predicate =[NSPredicate predicateWithFormat:@" radius = 10 OR hight = 200"];;
NSArray * results = [context executeFetchRequest:f error:nil];
NSLog(@"%@",results);
这会产生一个在执行获取请求时调用的键值异常,因为正方形没有半径,并且圆没有高度和宽度。
答案 0 :(得分:2)
您只能通过两种方式实现这一目标 - 向所有实体添加所有可能的属性(将radius
添加到Square
和width
,height
添加到{{1} })或执行两个获取请求,一个用于圆圈,一个用于方块。我是第二种方法。
Circle
答案 1 :(得分:2)
我会对Shape
实体进行非规范化:
在Shape
实体中包含所有属性(在任何情况下[对于SQLite商店]都是CoreData的内部实现)并且仅为特殊形状(Circle
创建实现(@dynamic), Square
,......)
您可以将此非规范化限制为仅需要搜索的属性。
备注:强>
Shape
实体中的非规范化属性设置默认值,因为继承实体在使用时仍会返回值:[object valueForKey:@"somepropertynamefromspecializedclass"];
。通过这种方式,他们会为此类密钥返回nil
。shapeType
实体添加Shape
媒体资源,这样您就可以限制搜索特定类型的Shape
这样,您只需要一次获取即可获得所需的对象,并使用一个FRC跟踪它们。
示例:
Shape
:[abstract entity](shapeType,name,radius,width,height):为此实体生成实现(Shape.h和Shape.m),但删除非规范化属性的实现(半径) ,宽度,高度)
所以你的Shape
.h文件如下:
@interface Shape : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * shapeType;
//radius ,width and height were removed (REMEMBER TO REMOVE THEM FROM YOUR .M FILE AS WELL)
@end
Shape
.m文件:
@implementation Shape
@dynamic name;
@dynamic shapeType;
@end
Circle
:[继承自Shape
]()
Circle
.h档案:
@interface Circle : Shape
@property (nonatomic,strong) NSNumber* radius;
@end
Circle
.m文件:
@implementation Circle
@dynamic radius;
@end
Rectangle
:[继承自Shape
]()
实现与Circle
现在您可以在代码中的某处执行:
Circle* c = (Circle*)[NSEntityDescription insertNewObjectForEntityForName:@"Circle" inManagedObjectContext:self.managedObjectContext];
c.name = @"circle";
c.shapeType = @"c";
c.radius = @(100);
Rectangle* rect = (Rectangle*)[NSEntityDescription insertNewObjectForEntityForName:@"Rectangle" inManagedObjectContext:self.managedObjectContext];
rect.name = @"rectangle";
rect.shapeType = @"r";
rect.width = @(150);
rect.height = @(200);
[self.managedObjectContext save:nil];
[self.managedObjectContext reset];
NSFetchRequest* r = [NSFetchRequest fetchRequestWithEntityName:@"Shape"];
r.predicate = [NSPredicate predicateWithFormat:@"width > %@ OR radius > %@",@(100),@(90)];
NSArray* res = [self.managedObjectContext executeFetchRequest:r error:nil];