i'm inserting new objects into the database by core data. Is there any way to check if there is any duplicate in the database before i insert the values in?
我正在通过核心数据将新对象插入数据库。在插入值之前,有没有办法检查数据库中是否有任何重复?
AccountDetails * newEntry = [NSEntityDescription insertNewObjectForEntityForName:@"AccountDetails" inManagedObjectContext:self.managedObjectContext];
newEntry.acc_date=date;
newEntry.bank_id=bank_id1;
NSError *error;
if (![self.managedObjectContext save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
[self.view endEditing:YES];
everytime i run the app , it reinsert the values again. i want to check if there is any new category in it if there isnt then i will add that new one in only.
每次我运行应用程序时,它会再次重新插入值。我想检查是否有任何新类别,如果没有,那么我将只添加新的类别。
thanks in advance..
提前致谢..
2 个解决方案
#1
7
You can fetch or you can count. Counting is much faster than fetching. Depends on what you are trying to do.
你可以取,或者你可以数。计数比获取快得多。取决于你想要做什么。
If you just want to insert new and skip duplicates then use -[NSManagedObjectContext countForFetchRequest: error:]
to determine if the object exists.
如果您只想插入新的并跳过重复项,请使用 - [NSManagedObjectContext countForFetchRequest:error:]来确定对象是否存在。
You can pre-build the predicate and just replace the unique value on each loop so that even the cost of the predicate is low. This is fairly performant but not the best solution because it hits the disk on each loop.
您可以预先构建谓词,只需替换每个循环上的唯一值,这样即使谓词的成本也很低。这是相当高效的,但不是最好的解决方案,因为它会在每个循环中击中磁盘。
Another option would be to change the fetch to have:
另一种选择是将fetch更改为:
- Just the unique value
- A NSDictionary result
只是独特的价值
NSDictionary结果
Then grab all of the unique values from your insertable array into an array of strings (for example) then do a single fetch with:
然后从可插入数组中获取所有唯一值到一个字符串数组(例如),然后使用以下命令执行单个提取:
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"myUnique in %@", uniqueIDArray]];
Then you have an array of uniques that ARE in the store already. From there as you loop over your objects you check against that array, if the unique in there you skip, otherwise you insert. That will yield the best performance for a straight insert or skip requirement.
然后你已经有了一系列商店中的唯一身份。当你循环遍历你的对象时,你可以从那里检查那个数组,如果你跳过了那个唯一的,那你就插入了。这将为直接插入或跳过要求产生最佳性能。
#2
0
You need to fetch from the db and check, your code will be doing something like this helper method I use frequently in my code, if the results.count is > 1, then DUPLICATE found :
您需要从db中获取并检查,您的代码将执行类似我在代码中经常使用的帮助器方法,如果results.count> 1,则发现DUPLICATE:
- (NSManagedObject*) findOrCreateObjectByValue:(id)value
propertyName:(NSString*)propertyName
entityName:(NSString*)entityName
additionalInfo:(NSDictionary*)additionalInfo
context:(NSManagedObjectContext*)context
error:(NSError* __autoreleasing*)error
{
NSManagedObject* res = nil;
NSFetchRequest* r = [NSFetchRequest fetchRequestWithEntityName:entityName];
[r setPredicate:[NSPredicate predicateWithFormat:@"%K == %@",propertyName,value]];
NSArray* matched = [context executeFetchRequest:r
error:error];
if (matched) {
if ([matched count] < 2) {
res = [matched lastObject];
if (!res) { //No existing objects found, create one
res = [NSEntityDescription insertNewObjectForEntityForName:entityName
inManagedObjectContext:context];
[res setValue:value
forKey:propertyName];
}
} else {
if (error) {
*error = [NSError errorWithDomain:@"some_domain"
code:9999
userInfo:@{@"description" : @"duplicates found"}];
}
}
}
return res;
}
#1
7
You can fetch or you can count. Counting is much faster than fetching. Depends on what you are trying to do.
你可以取,或者你可以数。计数比获取快得多。取决于你想要做什么。
If you just want to insert new and skip duplicates then use -[NSManagedObjectContext countForFetchRequest: error:]
to determine if the object exists.
如果您只想插入新的并跳过重复项,请使用 - [NSManagedObjectContext countForFetchRequest:error:]来确定对象是否存在。
You can pre-build the predicate and just replace the unique value on each loop so that even the cost of the predicate is low. This is fairly performant but not the best solution because it hits the disk on each loop.
您可以预先构建谓词,只需替换每个循环上的唯一值,这样即使谓词的成本也很低。这是相当高效的,但不是最好的解决方案,因为它会在每个循环中击中磁盘。
Another option would be to change the fetch to have:
另一种选择是将fetch更改为:
- Just the unique value
- A NSDictionary result
只是独特的价值
NSDictionary结果
Then grab all of the unique values from your insertable array into an array of strings (for example) then do a single fetch with:
然后从可插入数组中获取所有唯一值到一个字符串数组(例如),然后使用以下命令执行单个提取:
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"myUnique in %@", uniqueIDArray]];
Then you have an array of uniques that ARE in the store already. From there as you loop over your objects you check against that array, if the unique in there you skip, otherwise you insert. That will yield the best performance for a straight insert or skip requirement.
然后你已经有了一系列商店中的唯一身份。当你循环遍历你的对象时,你可以从那里检查那个数组,如果你跳过了那个唯一的,那你就插入了。这将为直接插入或跳过要求产生最佳性能。
#2
0
You need to fetch from the db and check, your code will be doing something like this helper method I use frequently in my code, if the results.count is > 1, then DUPLICATE found :
您需要从db中获取并检查,您的代码将执行类似我在代码中经常使用的帮助器方法,如果results.count> 1,则发现DUPLICATE:
- (NSManagedObject*) findOrCreateObjectByValue:(id)value
propertyName:(NSString*)propertyName
entityName:(NSString*)entityName
additionalInfo:(NSDictionary*)additionalInfo
context:(NSManagedObjectContext*)context
error:(NSError* __autoreleasing*)error
{
NSManagedObject* res = nil;
NSFetchRequest* r = [NSFetchRequest fetchRequestWithEntityName:entityName];
[r setPredicate:[NSPredicate predicateWithFormat:@"%K == %@",propertyName,value]];
NSArray* matched = [context executeFetchRequest:r
error:error];
if (matched) {
if ([matched count] < 2) {
res = [matched lastObject];
if (!res) { //No existing objects found, create one
res = [NSEntityDescription insertNewObjectForEntityForName:entityName
inManagedObjectContext:context];
[res setValue:value
forKey:propertyName];
}
} else {
if (error) {
*error = [NSError errorWithDomain:@"some_domain"
code:9999
userInfo:@{@"description" : @"duplicates found"}];
}
}
}
return res;
}