You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过单条Core Data查询按指定商品货架分组获取指定区域超市列表

Core Data 查询解决方案:按指定商品货架分组超市

首先明确你的实体关系:

  • StoreInventory:记录商品的货架信息,关联超市和食品
  • GroceryStore:超市实体,与StoreInventory是一对多关系
  • Product:食品实体,与StoreInventory是一对多关系

你的需求是完全可行的,而且不需要创建多余的StoreInventory实体,下面是Objective-C的实现方案:

思路说明

  1. 先筛选出Central和Southern区域的目标超市
  2. 通过Core Data表达式处理分组逻辑:
    • 对于售卖"Froot Loops"的超市,用对应商品的货架号作为分组键
    • 对于未售卖该商品的超市,用(No aisle)作为分组键
  3. 执行分组查询并整理成你期望的结果格式

Objective-C 代码实现

// 获取你的Core Data上下文(根据项目实际情况调整获取方式)
NSManagedObjectContext *context = [self managedObjectContext];

// 创建针对GroceryStore实体的查询请求
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"GroceryStore"];

// 1. 筛选区域:只保留Central和Southern的超市
NSPredicate *regionFilter = [NSPredicate predicateWithFormat:@"storeRegion IN %@", @[@"Central", @"Southern"]];
fetchRequest.predicate = regionFilter;

// 2. 构建分组键的表达式
// 筛选当前超市关联的、对应Froot Loops的StoreInventory集合
NSExpression *frootLoopsInventoryExpr = [NSExpression expressionForKeyPath:@"storeInventories.@filteredSet.product.productName == 'Froot Loops'"];
// 获取对应货架号的表达式
NSExpression *aisleExpr = [NSExpression expressionForKeyPath:@"storeInventories.@filteredSet.@distinctUnionOfObjects.aisle"];
// 无该商品时的默认分组键
NSExpression *noAisleExpr = [NSExpression expressionForConstantValue:@"(No aisle)"];
// 条件表达式:如果有Froot Loops的库存则取货架号,否则用默认值
NSExpression *groupKeyExpr = [NSExpression expressionForConditional:
    [NSExpression expressionForFunction:@"count:" arguments:@[frootLoopsInventoryExpr]] 
    greaterThan:[NSExpression expressionForConstantValue:@0] 
    then:aisleExpr 
    else:noAisleExpr];

// 包装表达式为可查询的属性描述
NSExpressionDescription *groupKeyDesc = [[NSExpressionDescription alloc] init];
groupKeyDesc.name = @"groupKey";
groupKeyDesc.expression = groupKeyExpr;
groupKeyDesc.expressionResultType = NSStringAttributeType;

// 3. 设置查询的属性、分组规则和结果类型
fetchRequest.propertiesToFetch = @[groupKeyDesc, [NSExpressionDescription expressionDescriptionForSelf]];
fetchRequest.propertiesToGroupBy = @[groupKeyDesc];
fetchRequest.resultType = NSDictionaryResultType;

// 4. 执行查询
NSError *error = nil;
NSArray *queryResults = [context executeFetchRequest:fetchRequest error:&error];
if (error) {
    NSLog(@"Core Data 查询错误: %@", error.localizedDescription);
    return;
}

// 5. 整理结果为你期望的分组格式
NSMutableDictionary *groupedStores = [NSMutableDictionary dictionary];
for (NSDictionary *resultDict in queryResults) {
    NSString *groupName = resultDict[@"groupKey"];
    // 处理货架号的格式,比如添加"Aisle "前缀
    if (![groupName isEqualToString:@"(No aisle)"]) {
        groupName = [NSString stringWithFormat:@"Aisle %@", groupName];
    }
    
    GroceryStore *store = resultDict[@"self"];
    if (!groupedStores[groupName]) {
        groupedStores[groupName] = [NSMutableArray array];
    }
    [groupedStores[groupName] addObject:store.storeName];
}

// 输出结果(可根据业务需求调整展示逻辑)
for (NSString *group in groupedStores.allKeys) {
    NSLog(@"Group \"%@\"", group);
    for (NSString *storeName in groupedStores[group]) {
        NSLog(@"    %@", storeName);
    }
}

注意事项

  • 请确保你的实体关系名称与代码中一致:比如GroceryStore到StoreInventory的关系名为storeInventories,如果你的项目中关系名不同,需要对应修改代码中的键路径。
  • 该方案通过Core Data的表达式和分组功能直接完成查询,无需为无关联的超市创建无效的StoreInventory实体,完全符合你的要求。

内容的提问来源于stack exchange,提问作者user2592842

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:22:44