加入Core Data中的表

时间:2012-07-31 22:03:52

标签: objective-c core-data join

我一直在尝试使用Core Data解决以下问题而没有任何运气。

我的模型有两个实体:Group和Element。两者都具有“name”属性和to-many关系,形式为:“group.elements”和“element.groups”(属于多个组的元素和具有多个元素的组)

我想以以下形式建立“过滤器”:

elements that belongs to "group_A" AND "group_B"

为了向用户显示如下内容:

The elements that match the filter belong to this set of groups in that quantity

举个例子,有:

  

Element_1 Group_A,Group_B,Group_C
  Element_2 Group_B,Group_C
  Element_3 Group_A,Group_B,Group_D
  Element_4 Group_A,Group_B,Group_D
  Element_5 Group_C,Group_D

答案应该是:Element_1,Element_3和Element_4与过滤器匹配,要显示的信息如下:

  

Group_A有3个元素
Group_B有3个元素
Group_C有1个元素
Group_D有2个元素

那个匹配过滤器

我怎么能把它放在Core Data NSExpression,NSPredicate等中?

感谢。



更新

我想我找到了解决这个问题的两种方法。


选项1

此选项使用“组名称过滤器”建立一个NSArray,并返回所有具有与条件匹配的元素数量的组,即使它为零(没有元素匹配)

有两个实体,“Grp”和“Elem”,它们之间有很多关系。

NSError *error = nil;

// Properties to be fetched
NSPropertyDescription *namePropDesc = [[[[self.moModel entitiesByName] objectForKey:@"Grp"] propertiesByName] objectForKey:@"name"];

// Variable group filter
NSArray *grpFilter = [NSArray arrayWithObjects:@"group_A", @"group_B", nil];

// Expression for counting elements
NSExpressionDescription *countExprDesc = [[NSExpressionDescription alloc] init];
[countExprDesc setExpression:[NSExpression expressionWithFormat:@"SUBQUERY(elems,$elem, SUBQUERY($elem.grps, $grp, $grp.name in %@).@count==%d).@count", grpFilter, grpFilter.count]];
[countExprDesc setExpressionResultType:NSInteger32AttributeType];
[countExprDesc setName:@"elementCount"];

// Create data fetching and set its properties
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Grp"];
[request setResultType:NSDictionaryResultType];
[request setPropertiesToFetch:[NSArray arrayWithObjects:namePropDesc,countExprDesc, nil]];

NSArray *results = [self.moContext executeFetchRequest:request error:&error];
NSLog(@"results = %@"results);


选项2

此选项使用“组名称过滤器”建立NSArray,并返回所有具有与条件匹配的元素数的组,而不包含没有任何元素的组。

在这种情况下,我创建了三个实体,Grp,Elem和RGE。将RGE作为一个中间实体,保持与另外两个的多对多关系。如果需要,此选项允许在组元素关联(创建日期等)中添加一些额外信息。 Grp和Elem之间没有关系。

注意:事实上,我需要在RGE实体中创建一个“常规”字段(名称)来应用@count函数。如果使用“to-many relationship字段”,则无法正确计数。

NSError *error = nil;


// Variable group filter
NSArray *grpFilter = [NSArray arrayWithObjects:@"group_A", @"group_B", nil];

// Create variable predicate string from "group's names filter"
NSMutableString *predicateStr = [[NSMutableString alloc] init];
for(int n=0;n<grpFilter.count;n++) {
    if(n>0) {
        [predicateStr appendString:@" AND "];
    }
    [predicateStr appendString:@"(ANY elem.rges.grp.name=%@)"];
}

// Filter to be applied
NSPredicate *filterQuery = [NSPredicate predicateWithFormat:predicateStr argumentArray:grpFilter];

// Expression for counting elements
NSExpressionDescription *countExprDesc = [[NSExpressionDescription alloc] init];
[countExprDesc setExpression:[NSExpression expressionWithFormat:@"name.@count"]];
[countExprDesc setExpressionResultType:NSInteger64AttributeType];
[countExprDesc setName:@"count"];

// Expression for grouping JUST by the group's name
NSExpressionDescription *grpNameExprDesc = [[NSExpressionDescription alloc] init];
[grpNameExprDesc setExpression:[NSExpression expressionWithFormat:@"grp.name"]];
[grpNameExprDesc setExpressionResultType:NSStringAttributeType];
[grpNameExprDesc setName:@"grpName"];

// THIS COULD JUST BE an NSPropertyDescription if you want the WHOLE "grp":
NSPropertyDescription *grpPropDesc = [[[[self.moModel entitiesByName] objectForKey:@"RGE"] propertiesByName] objectForKey:@"grp"];

// Create data fetching and set its properties
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"RGE"];
[request setResultType:NSDictionaryResultType];
[request setPropertiesToGroupBy:[NSArray arrayWithObjects: grpNameExprDesc, nil]];
[request setPropertiesToFetch:[NSArray arrayWithObjects:grpNameExprDesc, countExprDesc, nil]];
[request setPredicate:filterQuery];


NSArray *results = [self.moContext executeFetchRequest:request error:&error];
NSLog(@"results = %@",results);

1 个答案:

答案 0 :(得分:0)

我有类似的问题,我使用&#34;选项2&#34;解决了它。方法:Grouping three entities with many-to-many relationships

的问候。 佩德罗文图拉。