我认为我有一个难题。
我有两个实体,一个叫InProject
,有几个属性和一个关系。
这种关系与另一个名为Ins
的实体有关。
我正在编辑与Ins
相关的InProject
之一。我使用InProject
attribure ID
然后返回一个NSDictionary值,该值具有几个键值,其中一个键值为Ins
数组。然后我找到了我需要在for循环中编辑的Ins我编辑它们,但随后我变得不安,因为我不确定如何使用*更新Ins
我希望在下面的代码中提供一些帮助,以便在我覆盖我需要更新的InProject
属性后找出如何保存Ins
。
这是我的代码在经历了几个星期的战斗之后的样子...... :(
- (void)editSelectedins:(NSString *)projIDString UpdatedNSD:(NSMutableDictionary *)updatedNSD DPC:(int)dpc{
// get context
NSManagedObjectContext *context = [self managedObjectContext];
if (context == nil) {
NSLog(@"Nil");
}
else {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"InsProject" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSError *error;
NSMutableArray *InsProjectDictionaryArray = [[NSMutableArray alloc] init];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (InsProject *insProj in fetchedObjects) {
NSMutableDictionary *tempInsProjectDictionaryArray = [[ NSMutableDictionary alloc] init];
[tempInsProjectDictionaryArray setObject:insProj.companyName forKey:@"CompanyName"];
[tempInsProjectDictionaryArray setObject:insProj.projNo forKey:@"ProjNo"];
[tempInsProjectDictionaryArray setObject:insProj.desc forKey:@"Desc"];
[tempInsProjectDictionaryArray setObject:insProj.guid forKey:@"GUID"];
[tempInsProjectDictionaryArray setObject:insProj.projID forKey:@"ProjID"];
[tempInsProjectDictionaryArray setObject:insProj.ins forKey:@"ins"];
[InsProjectDictionaryArray addObject:tempInsProjectDictionaryArray];
}
// now that you have the InsProjects, choose the one you are curently working on in insView using the projectID
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ProjID==%@",projIDString];
[fetchRequest setPredicate:predicate];
// new array with one value that was created using the NSPredicate ProjID
NSArray *tempInsProjectArray = [InsProjectDictionaryArray filteredArrayUsingPredicate:predicate];
// get ins array out of the NSDictionary to edit
NSSet *inssForInsProject = tempInsProjectArray[0][@"ins"];
NSMutableArray *tempAllinss = [[NSMutableArray alloc] init]; // this will contain everything, that means all repeated values are included
for (Items* currItem in [inssForInsProject allObjects]) {
NSArray *keys = [[[currItem entity] attributesByName] allKeys];
NSDictionary *dict = [currItem dictionaryWithValuesForKeys:keys];
[tempAllinss addObject:dict];
}
NSArray *myArray = [tempAllinss copy];
// get the correct items from myArray anything whos dpc matches the dpc parameter of this method
NSMutableArray *editedinsArray = [[NSMutableArray alloc] init];
for (int i = 0; i < [myArray count]; i++) {
NSMutableDictionary *tempinssDictionary = [myArray objectAtIndex:i];
// if you get a match put it into the new editedinsArray to be edited
if ([[tempinssDictionary objectForKey:@"dpc"] integerValue] == dpc) {
[editedinsArray addObject:tempinssDictionary];
}
}
// by now you should have three things
// 1, access to your ins coredata object //this s wrong I actually have access to insProject
// 2, the values you need to be edited saved into a NSArray (editedinsArray, which will be used to check against and keep old values correct)
// 3, UpdatedNSD which will be used to update any values that need to be updated.
// go through your values and update the ins object
int i = 0;
for (ins *temp in editedinsArray) {
NSDictionary *currentEditedins = [editedinsArray objectAtIndex:i];
i++;
// these values should stay the same so use currentEditedins which contains old vals
NSString *stringToNumberDpc = [currentEditedins valueForKey:@"dpc"];
int tempDpcNum = [stringToNumberDpc integerValue];
NSNumber *dpcNumber = [NSNumber numberWithInt:tempDpcNum];
temp.dpc = dpcNumber;
NSString *totDQtyString = [currentEditedins valueForKey:@"totDQty"];
if ((NSNull *)totDQtyString == [NSNull null]) {
temp.totDQty = @"";
} else {
temp.totDQty = totDQtyString;
}
NSString *totShipString = [currentEditedins valueForKey:@"totShip"];
if ((NSNull *)totShipString == [NSNull null]) {
temp.totShip = @"";
} else {
temp.totShip = totShipString;
}
// values to be updated so use updatedNSD wthich was passed in as method param with the new vals
temp.newInsComp = [updatedNSD valueForKey:@"newInsComp"];
temp.newDryComp = [updatedNSD valueForKey:@"newDryComp"];
temp.updatedRow = [updatedNSD valueForKey:@"updatedRow"];
}
#warning --- I have no idea what to do here... i.e. how do I update the tempInsProjectArray.ins values I have just updated in the above for loop then save context which I hope would update insProj and the ins entities involved.
//save
[context save:&error];
}
}
任何帮助都会受到大力赞赏。你可以在#warning的代码底部看到我解释我遇到问题的地方。如果我在for循环中记录temp我完全看到更新的值我遇到的问题是如何更新我刚刚编辑的当前tempInsProjectArray.ins值?然后保存当然。
我希望我已经为您提供了足够的信息,但是我希望有人可以提供帮助。
答案 0 :(得分:3)
您的代码非常需要简化。一些基本规则:
InsProjectDictionaryArray
而是insProjectDictionaryArray
。 projNo
,而不是ProjNo
。 projNo
,而是projectNumber
。什么是Ins
?什么是“dcp”?Item
,而非Items
[array copy]
。NSNumber
。您想要完成的工作肯定可以通过几行代码完成。根据我的理解,我会尝试总结你想做的事情。
您的数据模型如下所示:
Project <----->> Item
项目处于称为ins
的多对多关系中。我将重命名此items
。我还假设您将ID重构为NSNumber
类型。
所有代码myArray
都可以替换为:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:"Project"];
request.predicate = [NSPredicate predicateWithFormat:@"projectID = %@", projectID];
request.fetchLimit = 1;
NSArray *fetchedObjects = [self.managedObjectContext
executeFetchRequest:request error:nil];
Project *project = fetchedObjects[0];
现在,您只需使用project.items
即可使用所有项目。我知道可能有多个项目具有dcp
类型的神秘属性int
(即托管对象的NSNumber
),等于传递的dcp
参数。
NSSet *matchingItems = [project.items filteredSetUsingPredicate:
[NSPredicate predicateWithFormat:@"dcp = %@", @(dcp)]];
现在变得有点模糊。如果ins
实际上是ins
类型,为什么你的for循环中有Item
类型?然后将它们转换为字典...这应该会生成编译器错误。或者您有另一个名为ins
而不是Ins
的类?
无论如何,如果您继续使用这些项目,您只需使用字典中传递的内容更新值:
for (Item *item in matchingItems) {
item.newInsComp = [updatedNSD valueForKey:@"newInsComp"];
item.newDryComp = [updatedNSD valueForKey:@"newDryComp"];
item.updatedRow = [updatedNSD valueForKey:@"updatedRow"];
}
[self.managedObjectContext save:nil];
完成!
BTW你可以通过将获取请求的实体名称设置为“Item”并设置以下谓词来缩短它:
[NSPredicate predicateWithFormat:@"project.projectID = %@ && dcp = %@",
projectID, @(dcp)];
答案 1 :(得分:0)
如果您了解自己的InProject
,那么更新与该项目相关的Ins
就是编辑托管对象的属性值。
为什么不使用谓词来获取InProject
的NSManagedObject,然后从中拉出关系并编辑值?
NSManagedObjectContext *context = [self managedObjectContext];
if (!context) {
return;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"InsProject" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
// Set the predicate on the Core Data fetch request instead
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"ProjID==%@",projIDString];
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
// We now have an array that has objects matching the projectIdString
// Might want to do some additional checks if you're only expecting zero or one objects
InsProject *aProject = [fetchedObjects lastObject];
// If we have no project, no point going any further
if ( !aProject ) return;
// On this NSManagedObject is an NSSet property with all related Ins objects
for ( Ins *anIns in aProject.ins ) {
// If our Ins item matches the passed dpc...
if ( [ins.dpc integerValue] == dpc ) {
// ...we have a match, edit properties
ins.dpc = @(dpc);
ins.newInsComp = [updatedNSD valueForKey:@"newInsComp"];
ins.newDryComp = [updatedNSD valueForKey:@"newDryComp"];
ins.updatedRow = [updatedNSD valueForKey:@"updatedRow"];
}
}
// These are managed objects, so saving the context saves all the changes
NSError *saveError;
[context save:&saveError];
if ( saveError ) {
NSLog(@"Save error: %@", [error localizedDescription]);
}