浏览核心数据对象图[2] [英] Navigating the Core Data Object Graph [2]

查看:101
本文介绍了浏览核心数据对象图[2]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

昨天我问了一个问题,我真的应该开始使用更简单的例子。将我的问题提炼成基本知识后,我已经使用现有的SO问题和答案解决了我的问题。



我在这里总结我的问题解决方案),因为我不认为有任何职位,解释这一点很清楚。作为对Core Data的新手,并努力摆脱SQL的概念,我欢迎关于我的解决方案是否合适的反馈,以及是否有更好的方法来建模问题。





给定以下对象模型,它有三个实体A,B和C by to many relationship:



如何能够识别父 实体,它们有孙子 C 具有特定属性的实体?例如,使用这些示例实体及其关系:





如何找到我们的实体 A



我已经能够实现这是使用 NSPredicate SUBQUERY 关键字c>。这里是为我工作的代码片段(假设你已经设置了管理对象上下文等):

  NSError * error = nil; 
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription * entity = [NSEntityDescription entityForName:@EntityAinManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate * predicateTemplate = [NSPredicate predicateWithFormat:@(0!= SUBQUERY(child,$ a,(0!= SUBQUERY($ a.child,$ child,$ child.tag ==%@) count))。@ count),@YES];
[fetchRequest setPredicate:predicateTemplate];
NSArray * test = [context executeFetchRequest:fetchRequest error:& error];

将所有重要的NSPredicate字符串分成几行:

 (0!= SUBQUERY(child,
$ a,
(0!= SUBQUERY($ a.child,
$ child,
$ child.tag ==%@)。@ count)
)。@ count

重要的是我们选择 EntityA 来工作,然后在嵌套的子查询中通过实体的关系。我期望这可以重复几个深度。不是最直观的东西放在一起...但它的工作原理。评论欢迎。

解决方案

我从来没有尝试过使用子查询,这很酷,很好看看它的例子。你应该添加解答作为问题的答案实际上!



我可能会像Abizern建议的,因为这是一个树状的层次结构,它更容易遍历


$ b

在代码中,这看起来像:

  NSManagedObjectContext * moc = APPDELEGATE.managedObjectContext; 
NSFetchRequest * request = [NSFetchRequest new];
[request setEntity:[NSEntityDescription entityForName:@EntityCinManagedObjectContext:moc]];
[request setPredicate:[NSPredicate predicateWithFormat:@tag = YES]];
NSError * fetchError = nil;
NSArray * children = [moc executeFetchRequest:request error:& fetchError];

children 是一个 EntityC 与谓词匹配的对象。下一步是获取一组独特的 EntityA 对象,它们是这些对象的祖父。我们可以在这里使用键值编码:

  NSArray * grandParents = [children valueForKeyPath:@parent。@ distinctUnionOfObjects。 parent]; 

在这种情况下,为了提高效率,我们可能需要预取 parent.parent keypath:

  [request setRelationshipKeyPathsForPrefetching:@ [@] parent .parent]]; 

希望这有助于!


I asked a question yesterday where I really should have started with a simpler example. Having distilled my question to the basics, I've managed to solve my problem using existing SO questions and answers.

I'm summarising my question here (and providing my own solution) because I don't think there are any posts that explain this clearly enough. Being new to Core Data and struggling to get away from SQL concepts, I'd welcome feedback on how appropriate my solution is, and if there are better ways of modelling the problem.

Question

Given the following object model, that has three entities A, B and C, each linked by to-many relationships:

How is it possible to identify the parent A entities, that have grandchildren C entities with a particular attribute? By example, using these sample entities and their relationships:

How can I find our which entity A s have child entity C s with the Tag:Yes?

Solution

I've been able to achieve this is using the SUBQUERY keyword of NSPredicate. Here is the code snippet that worked for me (assuming you've set up your managed object context etc):

NSError *error = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"EntityA" inManagedObjectContext:context];   
[fetchRequest setEntity:entity];
NSPredicate *predicateTemplate = [NSPredicate predicateWithFormat:@"(0 != SUBQUERY(child, $a, (0 != SUBQUERY($a.child, $child, $child.tag == %@).@count)).@count)", @"YES"]; 
[fetchRequest setPredicate:predicateTemplate];
NSArray *test = [context executeFetchRequest:fetchRequest error:&error];

Breaking the all important NSPredicate string onto several lines:

(0 != SUBQUERY(child, 
               $a, 
               (0 != SUBQUERY($a.child,
                              $child, 
                              $child.tag == %@).@count)
               ).@count
)

The important part is we are selecting the EntityA to work from and then in the nested subquery working through the child relationships of the entities. I expect this can be repeated for several depths. Not the most intuitive thing to put together... but it works. Comments welcome.

解决方案

I've never tried to use a subquery before, that's very cool and good to see an example of it. You should add the solution as an answer to the question actually!

I would have probably done as Abizern suggested, since this is a tree-like hierarchy and its easier to traverse up the tree using to-one relationships.

In code this looks like:

NSManagedObjectContext *moc = APPDELEGATE.managedObjectContext;
NSFetchRequest *request = [NSFetchRequest new];
[request setEntity:[NSEntityDescription entityForName:@"EntityC" inManagedObjectContext:moc]];
[request setPredicate:[NSPredicate predicateWithFormat:@"tag = YES"]];
NSError *fetchError = nil;
NSArray *children = [moc executeFetchRequest:request error:&fetchError];

children is an array of EntityC objects that match the predicate. The next step is getting a set of unique EntityA objects that are the "grandparents" of these. We can take advantage of key-value coding here:

NSArray *grandParents = [children valueForKeyPath:@"parent.@distinctUnionOfObjects.parent"];

In this case, for efficiency, we'd probably want to prefetch the parent.parent keypath during our initial fetch request:

[request setRelationshipKeyPathsForPrefetching:@[@"parent.parent"]];

Hope this helps!

这篇关于浏览核心数据对象图[2]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆