0

我知道有很多关于确定核心数据实体是否唯一的讨论,但是我在理解人们抛出的各种解决方案时遇到了很多麻烦。希望有人可以为我提供一个简单的解决方案。

情况:

我有一个基本上是多对多关系的实体(事件->参加者<-人)。人员是对通讯簿条目的引用(我将 AddressBookID、firstName、lastName 和 createdOn 日期存储在 People 实体中)。在事件表中,我有关于事件的详细信息。在参加者表中,我与 Event(事件)和 People(人)以及 createdOn 日期有关系以进行排序。

问题:我想在插入参加者记录之前检查用户是否已将人员添加到事件中。

在传统数据库中,我会创建一个唯一键约束。当我尝试插入副本时,它会抛出一个错误,我会捕获它并继续前进(可能用最新数据更新现有记录)。

我尝试了以下方法:

#pragma mark - Selected People Delegate
-(void)returnPeople:(NSMutableArray *)selectedPeople
{
    NSError *error = nil;
    Attendee *newAttendee; 

    for (Attendee *selectedPerson in selectedPeople) {

        if (self.context == nil) {
            NSLog(@"NSManagedObjectContext is nil");
//            return nil;
        }


         newAttendee = [NSEntityDescription insertNewObjectForEntityForName:@"Attendee" inManagedObjectContext:context];


        [event addAttendeeObject:newAttendee];

        newAttendee.createdOn = [NSDate date];

        newAttendee.event = event;
        newAttendee.person = selectedPerson;


        NSLog(@"Person ID: %@", [selectedPerson.objectID description] );

        if ([self uniqueEntityExistsWithEnityName:@"Attendee" UniqueKey:@"person" UniqueValue:[selectedPerson.objectID description] SortAttribute:@"createdOn" ManagedObjectContext:context]) {
            NSLog(@"Attendee Exists!");
        }

        if (![context save:&error]) {
            // Handle the error.
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }

        error = nil;
        self.eventAttendee = nil;

        [self.attendees insertObject:newAttendee atIndex:0];

        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];

        [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                              withRowAnimation:UITableViewRowAnimationFade];

        [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];

        [FlurryAnalytics logEvent:@"Event Attendee Added"];


    }


}

#pragma mark - Core Data - Manage Attendees

-(BOOL)uniqueEntityExistsWithEnityName:(NSString*)entityName UniqueKey:(NSString*) uniqueKey UniqueValue:(NSString*)uniqueValue SortAttribute:(NSString*)sortDescriptorAttribute ManagedObjectContext:(NSManagedObjectContext*) context1;
{
    BOOL returnValue = NO;

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];

    //what is the correct predates to compare the text an string core data property against a passed in string?
    //    request.predicate = [NSPredicate predicateWithFormat:@"unique= %@", uniqueValue];
    request.predicate = [NSPredicate predicateWithFormat:@"%@=%@", uniqueKey, uniqueValue];

    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:sortDescriptorAttribute ascending:YES];
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];   

    NSError *error = nil;
    NSArray *matches = [context1 executeFetchRequest:request error:&error];
    if (!matches)
    {
        NSLog(@"Error: no object matches");
    }
    else if([matches count] > 1) {
        NSLog(@"Error: More than one object for unique record");
        returnValue = YES;

    } else if ([matches count] == 0) {
        returnValue = NO;
    } else {
        returnValue = YES;
    }

    return returnValue;
}

提前感谢您的帮助!!!

杰森

4

1 回答 1

0

编辑 评论后。

好的,您的问题是没有将人员添加到事件。您的问题是将参加者添加到事件中,该参加者具有某种关系。

在这种情况下,我会先做一个简单的 fetch 类似于...

// Find all Attendee objects that are linked to both our event and person
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Attendee"];
request.predicate = [NSPredicate predicateWithFormat:@"(event.name = %@) AND (person.name = %@)", eventName, personName];

然后,您可以进行提取。您将取回包含您要查找的事件和指定人员的所有参加者对象。现在,如果您一无所获,则该人尚未添加为与会者。

如果您有很多对象,还有其他更快的方法来执行此操作(取决于具有索引的属性和其他因素)。使用连接(即谓词中的关系)并不是很快,除非您指定索引属性,否则所有搜索都是线性的。

于 2012-04-29T20:23:31.403 回答