【问题标题】:How would I form a fetch result predicate based on this data model?我将如何基于此数据模型形成提取结果谓词?
【发布时间】:2012-08-19 02:47:56
【问题描述】:

我将如何返回与食谱相关的所有成分,特别是从属于事件的食谱中?然后按过道订购?

进一步解释:

用户有一个食谱对象的“食谱书”,它与成分有关系。用户在计划准备食谱时会将食谱与事件相关联。我试图提取的数据是属于食谱的成分列表,属于事件,由 Aisle 排序。基本上是一个“杂货清单”。

关于什么是 Event 对象的进一步解释: 事件允许重复的食谱。假设我要连续 3 天(3 个单独的事件)吃一个煎鸡蛋(成分 =“1 个新鲜鸡蛋”),我希望购物清单包含 3 次“1 个新鲜鸡蛋” - 每个事件一个实例。

这是我的 fetch 请求,它没有返回任何结果 - 我认为问题的症结在于谓词:

NSFetchRequest *request = [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Ingredient"    inManagedObjectContext:[self managedObjectContext]];
[request setEntity:entity];

// get ingredients of recipes that belong to events
[request setPredicate:[NSPredicate predicateWithFormat:@"Ingredient.recipe == Event.recipe"]];

// sort by "aisle"
NSSortDescriptor *sortDescriptorCategory = [NSSortDescriptor sortDescriptorWithKey:@"aisle" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObjects:sortDescriptorCategory, nil];

// create nsfrc with "aisle" as sectionNameKeyPath
NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"aisle" cacheName:@"MyFRCCache"];
frc.delegate = self;
NSError *error = nil;
if (![frc performFetch:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}
self.fetchedResultsController = frc;

感谢 Martin R 的问题,我进一步充实了这个问题。这是一些示例数据和所需的输出:

食谱

Z_PK = 1, ZTITLE = "燕麦片"
Z_PK = 2, ZTITLE = "花生酱和果冻三明治"
Z_PK = 3, ZTITLE = "烤奶酪三明治"
Z_PK = 4, ZTITLE = "炖牛肉"
Z_PK = 5, ZTITLE = "汉堡包"
...加上更多不会包含在 fetch 结果中的食谱 ...

事件

Z_PK = 1,ZTITLE = "早餐 1",ZRECIPE = 1
Z_PK = 2,ZTITLE = "午餐 1",ZRECIPE = 2
Z_PK = 3, ZTITLE = "晚餐", ZRECIPE = 4
Z_PK = 4, ZTITLE = "Breakfast 2", ZRECIPE = 1 // 注意食谱重复
Z_PK = 5,ZTITLE = “午餐 2”,ZRECIPE = 3
Z_PK = 6, ZTITLE = "晚餐 2", ZRECIPE = 5

成分

Z_PK = 1, ZTITLE = "1 杯燕麦片", ZRECIPE = 1, ZAISLE = 4
Z_PK = 2, ZTITLE = "2 杯牛奶", ZRECIPE = 1, ZAISLE = 2
Z_PK = 3, ZTITLE = "2 块白面包", ZRECIPE = 2, ZAISLE = 5
Z_PK = 4,ZTITLE = “1 汤匙果冻”,ZRECIPE = 2,ZAISLE = 4
Z_PK = 5, ZTITLE = "1 汤匙花生酱", ZRECIPE = 2, ZAISLE = 4
Z_PK = 6, ZTITLE = "2 块黑麦面包", ZRECIPE = 3, ZAISLE = 5
Z_PK = 7, ZTITLE = "1 个奶酪片", ZRECIPE = 3, ZAISLE = 2
Z_PK = 8,ZTITLE = “1 磅夹头烤肉”,ZRECIPE = 4,ZAISLE = 3
Z_PK = 9,ZTITLE = “2 根胡萝卜”,ZRECIPE = 4,ZAISLE = 1
Z_PK = 10,ZTITLE = "2 个土豆",ZRECIPE = 4,ZAISLE = 1
Z_PK = 11, ZTITLE = "1 个汉堡面包", ZRECIPE = 5, ZAISLE = 5
Z_PK = 12, ZTITLE = "1/4 磅汉堡", ZRECIPE = 5, ZAISLE = 3

过道

Z_PK = 1, ZTITLE = "生产", ZDISPLAYORDER = 1
Z_PK = 2, ZTITLE = "乳制品", ZDISPLAYORDER = 2
Z_PK = 3, ZTITLE = "肉类", ZDISPLAYORDER = 3
Z_PK = 4, ZTITLE = "干货和罐头", ZDISPLAYORDER = 4
Z_PK = 5, ZTITLE = "面包店", ZDISPLAYORDER = 5

期望的输出(按 Aisle ZDISPLAYORDER 排序,粗体项目为章节标题)

制作
-2 胡萝卜
-2 土豆
乳制品
-2 杯牛奶
-2 杯牛奶 // 第二项,因为配方有两个实例
-1 片奶酪
肉类
-1 磅。夹头烤
-1/4 磅汉堡
干货和罐头
-1杯燕麦片
-1 杯燕麦片//第二项,因为有两个配方实例
-1汤匙。果冻
-1 汤匙花生酱
面包店
-2 块白面包
-2 片黑麦面包
-1个汉堡面包

【问题讨论】:

  • 究竟是什么意思“属于所有事件的食谱”?您真的只想要属于数据库中所有事件的食谱吗?或者您是否有一个事件列表并想要属于该列表中所有事件的食谱?还是有什么不同?
  • 我看到了混乱。我想要一个与事件相关的食谱列表。换句话说 - 事件食谱中的所有成分。我更新了代码中的注释,并进一步解释了事件的含义。
  • 在您的关系模型中,一个事件只有一个配方。但是在你的文字中你说一个事件可以有多个食谱。
  • 我想我现在看到了您正在尝试做的事情,但这可能是不可能的。获取请求只能返回符合特定条件的对象列表(例如成分列表)。对象也可以排序。但是 fetch 请求的结果不会多次包含同一个对象!所以像“购物清单包含'1个新鲜鸡蛋'3次”这样的东西是不可能的。
  • 更多混乱:您定义了一个未使用的NSFetchedResultsController。 FRC 通常用于在表视图中显示获取请求的结果,并在数据更改时对表进行“实时更新”。

标签: cocoa core-data nsfetchrequest


【解决方案1】:

提取请求不能(据我所知)返回同一托管对象的重复条目。所以我最接近的解决方案如下。

获取所有成分并根据aisle.displayOrder将它们分成部分。在每个部分中,按照自己的显示顺序对成分进行排序:

NSSortDescriptor *sort1 = [NSSortDescriptor sortDescriptorWithKey:@"aisle.displayOrder" ascending:YES];
NSSortDescriptor *sort2 = [NSSortDescriptor sortDescriptorWithKey:@"displayOrder" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObjects:sort1, sort2, nil];

NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:request
    managedObjectContext:self.managedObjectContext
    sectionNameKeyPath:@"aisle.displayOrder"
    cacheName:@"fetchControllerCache"];

然后您可以计算每种成分的事件数量(并将其显示在您的表格中):

int numberOfEvents = theIngredient.recipe.events.count;

【讨论】:

    【解决方案2】:

    我想你会想要一个谓词:

    recipe.events.@count > 0
    

    这将使您在任何Recipes 中使用Ingredients,这些Event 是任何Event

    或者,如果您正在寻找在任何Recipe 中使用的Ingredients 以获取特定的Event,则为:

    [NSPredicate predicateWithFormat:@"ANY recipe.events = %@", specificEvent]
    

    您的排序描述符可能是aisle.displayOrder,而不仅仅是aisle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-08
      • 1970-01-01
      相关资源
      最近更新 更多