我正在开发一个具有核心数据的IOS应用程序,我必须预加载与核心数据多对多关系的数据。我有三个表,其中包含超级市场,产品和称为超级市场Toproduct的中间表,用于存储超级市场与产品之间的关系。正如我所说,超市和产品实体之间存在许多关系,因此我需要创建一个中间表来指示这些关系。我的问题是,以多对多关系将JSON格式的数据预加载到我的核心数据中的最佳实践是什么。在Apples参考文档中,声明了无需创建中间表,因为coredata为我们创建了一个中间表。但是,如何在不带中间表的情况下预加载日期时定义多对多关系?顺便一提,所有数据都是静态的,因此无需在表中插入新数据,我只需要获取数据及其相关的超级市场或产品。请注意,联接表具有两个独立的属性,分别称为priceofProductforGivenMarket和primaryProductforGivenMarket。这是我的数据的JSON表示形式,也是我将在核心数据中创建的模型:
Supermarket:
name
location
phone number
Product:
name
price
company
supermarketToproduct:
nameofsupermarket
nameofproduct
priceofProductforGivenMarket
primaryProductforGivenMarket
我将创建三个实体,Supermarket,Product和SupermaketProductDetails,其属性和关系如下:
Supermarket:
Attributes: name, location, phone number
Relationship (to many): productDetails
Product:
Attributes: name, price, company
Relationship (to many): supermarketDetails
SupermarketProductDetails:
Attributes: priceofProductforGivenMarket, primaryProductforGivenMarket
Relationships: (to one) supermarket, (to one) product
在Xcode中,指示Supermarket实体中productDetails关系的“目标”是SupermarketProductDetails实体(具有反向超级市场),同样将SupermarketProductDetails实体设置为Product实体中具有反向产品的超级市场细节的目的地。
然后,我将首先为超级市场解析您的JSON数据,创建超级市场对象并设置名称,位置和电话号码,但无需为产品关系输入任何内容。同样,解析产品JSON并创建所有Products对象。然后,我将解析联接表,并创建SupermarketProductDetails对象。根据您的JSON数据设置属性,并执行获取操作以获取具有正确名称的Supermarket实体,同样获取具有正确名称的Product实体,然后直接设置这些关系。
编辑:假设您将联接表中的每一行解析为四个NSStrings:超级市场名称,产品名称,priceofGivenMarket和primaryProductforGivenMarket。然后每行...
// First fetch the correct Supermarket...
NSFetchRequest *supermarketFetch = [NSFetchRequest fetchRequestWithEntityName:@"Supermarket"]
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@",nameofsupermarket];
supermarketFetch.predicate = predicate;
NSError *error;
NSArray *results = [context executeFetchRequest:supermarketFetch error:&error];
// should really check for errors, and that we get one and only one supermarket
NSLog(@"Supermarket fetch returned %i results",[results count]); // should be only 1!
mySupermarket = (NSManagedObject *)[results firstObject];
if (![[mySupermarket valueForKey:@"name"] isEqualToString:nameofsupermarket]) {
NSLog(@"Wrong supermarket fetched");
}
// Now fetch the product...
NSFetchRequest *productFetch = [NSFetchRequest fetchRequestWithEntityName:@"Product"]
predicate = [NSPredicate predicateWithFormat:@"name like %@",nameofproduct];
productFetch.predicate = predicate;
results = [context executeFetchRequest:productFetch error:&error];
// should really check for errors, and that we get one and only one product
NSLog(@"Product fetch returned %i results",[results count]); // should be only 1!
myProduct = (NSManagedObject *)[results firstObject];
if (![[myProduct valueForKey:@"name"] isEqualToString:nameofproduct]) {
NSLog(@"Wrong product fetched");
}
// Now create the SupermarketProductDetails entity:
NSManagedObject *mySupermarketProductDetails = [NSEntityDescription insertNewObjectForEntityForName:@"SupermarketProductDetails" inManagedObjectContext:context];
// set attributes...
[mySupermarketProductDetails setValue:primaryProductForGivenMarket forKey:@"primaryProductForGivenMarket"];
[mySupermarketProductDetails setValue:priceOfProductForGivenMarket forKey:@"priceOfProductForGivenMarket"];
// set relationships...
[mySupermarketProductDetails setValue:mySupermarket forKey:@"supermarket"];
[mySupermarketProductDetails setValue:myProduct forKey:@"product"];
[context save:&error];
// should check for errors...
请注意,您只需要设置这些关系的一方-CoreData会为您更新另一方(即,它将mymymarketDetails添加到myProduct的超级市场详细信息集中,等等)。另请注意,(一对一)关系(例如,超级市场)的“值”是目标对象本身(例如,mySupermarket);您不使用名称或其他任何键。Coredata(隐藏在基础sql表中)使用唯一的objectID进行链接。
(执行此操作可能有更有效的方法,而不是对每个SupermarketProductDetails条目进行两次访存,但这是可行的。)
EDIT2:请注意,以上假设您的实体都被实现为NSManagedObjects。如果为每个实体创建了单独的子类,则可以简化上面的一些代码。例如,valueForKey:和setValue:forKey:可以被等效的属性访问器方法替换,该方法使用点表示法,例如:
[mySupermarketProductDetails setValue:primaryProductForGivenMarket forKey:@"primaryProductForGivenMarket"];
会成为:
mySupermarketProductDetails.primaryProductForGivenMarket = primaryProductForGivenMarket;
和
[mySupermarket valueForKey:@"name"]
可以替换为:
mySupermarket.name
同样,应使用适当的子类而不是NSManagedObject创建对象。例如。
NSManagedObject *mySupermarketProductDetails = [NSEntityDescription insertNewObjectForEntityForName:@"SupermarketProductDetails" inManagedObjectContext:context];
会成为
SupermarketProductDetails *mySupermarketProductDetails = [NSEntityDescription insertNewObjectForEntityForName:@"SupermarketProductDetails" inManagedObjectContext:context];
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句