Core data 查询/筛选具有非键值complient的公共父级的核心数据实体
有没有办法创建谓词查询来筛选子实体?我希望能够返回一个结果集,并将过滤应用于子级 例如,我有形状。圆圈和正方形是形状,我想这样做:Core data 查询/筛选具有非键值complient的公共父级的核心数据实体,core-data,nspredicate,Core Data,Nspredicate,有没有办法创建谓词查询来筛选子实体?我希望能够返回一个结果集,并将过滤应用于子级 例如,我有形状。圆圈和正方形是形状,我想这样做: NSManagedObjectContext * context = [self managedObjectContext]; Circle * c = [NSEntityDescription insertNewObjectForEntityForName:@"Circle" inManagedObjectContext:context]; c.radius =
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);
这会产生一个键值异常,在执行提取请求时将调用该异常,因为正方形没有半径,而圆没有高度和宽度。您只能通过两种方法来实现这一点-向所有实体添加所有可能的属性(将
半径
添加到正方形
和宽度
,高度
添加到圆形
)或执行两个提取请求,一个用于圆形,一个用于方形。我支持第二种方法
NSFetchRequest * f = [NSFetchRequest fetchRequestWithEntityName:@"Circle"];
f.predicate =[NSPredicate predicateWithFormat:@" radius = 10"];
NSArray * results = [context executeFetchRequest:f error:nil];
if(results == nil) { results = @[]; }
f = [NSFetchRequest fetchRequestWithEntityName:@"Square"];
f.predicate = [NSPredicate predicateWithFormat:@"height = 200"];
results = [results arrayByAddingObjectsFromArray:[context executeFetchRequest:f error:nil]];
我会去规范化
形状实体:
在形状
实体中包括所有属性(在任何情况下[对于SQLite存储]都是CoreData的内部实现),并且仅为特殊形状(圆形
,方形
,…)创建实现(@dynamic)。
您可以将此非规范化限制为仅需要搜索的属性
备注:
您可能希望避免为形状
实体中的非规范化属性设置默认值,因为继承实体在使用时仍将返回值:[object valueForKey:@“somepropertynamefromspecializedclass”];
。这样,它们将为此类键返回nil
您可能还希望将shapeType
属性添加到Shape
实体中,以便您可以将搜索限制为仅搜索特定类型的Shape
s
这样,您只需要一次抓取即可获得所需的对象,并使用单个FRC跟踪它们
例如:
Shape
:[abstract entity](shapeType、name、radius、width、height):生成此实体(Shape.h和Shape.m)的实现,但删除已非规范化属性(radius、width、height)的实现
因此,您的形状
.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
@implementation Circle
@dynamic radius;
@end
圆
:[继承自形状
]()
Circle
.h文件:
@interface Circle : Shape
@property (nonatomic,strong) NSNumber* radius;
@end
Circle
.m文件:
@implementation Shape
@dynamic name;
@dynamic shapeType;
@end
@implementation Circle
@dynamic radius;
@end
矩形
:[从形状继承)()
与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];
您尝试过吗?尝试时会发生什么?如果有错误,您会得到什么?这会产生一个键值错误,因为radius不是Square的成员。在执行提取请求期间?这是在提取请求期间