2012-04-28 19 views
0

コアデータエンティティがユニークであるかどうかを判断することについて多くの議論があったことは知っていますが、私は人が投げ捨てたさまざまな解決策を理解するのに多くの問題があります。うまくいけば、誰かが私にシンプルなソリューションを提供することができます。コアデータの既存エンティティ

状況:

私は基本的に多対多の関係(イベント - >出席者< - ピープル)であるエンティティを持っています。人々はアドレス帳のエントリへの参照です(私はPeopleエンティティにAddressBookID、firstName、lastNameおよびcreatedOn日付を格納しています)。イベントテーブルには、イベントの詳細があります。出席者テーブルには、イベント(イベント)と人(人)との関係と、ソートのための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; 
} 

感謝を!コメントの後

ジェイソン

+0

コードの問題点は何ですか? –

+0

私のコードの問題は、uniqueEntityExistsWithEnityNameメソッドを使うと、人が既に追加されていることが決して見つからないということです。したがって、TRUEを返す必要があるときは、基本的にFALSEを返します。 – JasonBub

答えて

0

EDIT

問題はありません。問題は、イベントに人を追加することではありません。あなたの問題は、その出席者が特定の関係を持っているイベントに出席者を追加することです。

その場合は、私が最初にシンプルで、あなたがあなたのフェッチを行うことができます次に

// 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]; 

...に似フェッチんでしょう。探しているイベントと指定された人物の両方を含むAttendeeオブジェクトがすべて返されます。今、何も戻って来なければ、その人は出席者として追加されていません。

オブジェクトがたくさんある場合は、これを行う他の方法があります(インデックスやその他の要素を持つ属性によって異なる)。結合(つまり、述語における関係)は超高速ではなく、索引属性を指定しない限り、すべての検索は線形です。

+0

こんにちはジョディ、私の問題についていくつかの洞察を提供する時間を取ってくれてありがとう、ありがとう。それは有り難いです!あなたの応答に関して、私はTo-Many Relationshipをチェックしましたが、同じ人を同じイベントの複数のタイトルに追加することができます(基本的に一意のキー制約違反を作成します)。私のテーブルビューの中で、私は同じ人物が何度も追加されているのを見ています。 – JasonBub

+0

注:私は回避策として次のソリューションを実装しました。選択したイベントのすべての出席者を含むNSArrayを作成します。次に、配列をループして、追加しようとしているPersonに対して各PersonのobjectIDの説明をチェックします。私がそれを見つけたら、私はYESを返し、そうでなければNOを返します。これは機能していますが、実際には非効率的です(つまり、多くの出席者がいる場合は、各イベントごとに少数になります)。)いずれにしても、私はこれをもう一日か二日間開いたままにしておき、ケースをコードで更新します。 – JasonBub

+0

こんにちはジョディ、あなたの記事を別の時間を読んだ後、私は私の3つのテーブル(エンティティ)=イベント、出席者&人を持っていることを私の元の質問は明確にレイアウトしていないことが分かった。出席者は関係(イベントと人物)を持っていなければなりません。重複があるかどうかを判断するには、EventとPersonの両方のobjectIDをチェックする必要があると思います。 – JasonBub

関連する問題