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的成员。在执行提取请求期间?这是在提取请求期间