このコアデータを理解するのに少し苦労しています。一意のIDで新しいエントリを作成するにはどうすればよいですか? SQLでは、1つのフィールドを自動インクリメントフィールドとして宣言するだけです。ここではそのようなものは見ていませんが、何かが足りない可能性があります。 NSIntegerフィールドの自動インクリメントが必要なため、データベースにアイテムを手動で追加するときに、何らかの形式の参照があります。
あなたの言ったことには同意しますが、コアデータの背後にはIDメカニズムがあります。 IDは確かにCore-Dataによって管理されますが、次の方法で取得できます。
NSManagedObjectID *moID = [managedObject objectID];
詳細については、以下を参照してください。 Core Data Programming Guide
それはCoreDataの仕組みではありません。
CoreDataでは、エンティティのインスタンスを作成します。各インスタンスは一意です。その後、必要に応じてインスタンスを取得および操作します。 CoreDataは、インスタンスを一意に識別するなど、永続性を管理します。
従来のリレーショナルデータベースについて知っているすべてのことから離れてください。
CoreDataは、永続性のようなデータベースをはるかに超える機能を提供する、非常に強力なテクノロジです。多くのコード行を節約し、それを採用すれば非常にうまく機能します。
このクラス関数は、idプロパティに対して次に利用可能な数を返します(整数プロパティである必要があります)。
自動増分値ジェネレーターと呼びます。私はまだそのためのobjectIDがあることに他の人に同意しますが、時々あなただけの番号が必要です。
この関数は、エンティティのNSManagedObjectサブクラスに配置できます。
+(NSNumber *)nextAvailble:(NSString *)idKey forEntityName:(NSString *)entityName inContext:(NSManagedObjectContext *)context{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSManagedObjectContext *moc = context;
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:moc];
[request setEntity:entity];
// [request setFetchLimit:1];
NSArray *propertiesArray = [[NSArray alloc] initWithObjects:idKey, nil];
[request setPropertiesToFetch:propertiesArray];
[propertiesArray release], propertiesArray = nil;
NSSortDescriptor *indexSort = [[NSSortDescriptor alloc] initWithKey:idKey ascending:YES];
NSArray *array = [[NSArray alloc] initWithObjects:indexSort, nil];
[request setSortDescriptors:array];
[array release], array = nil;
[indexSort release], indexSort = nil;
NSError *error = nil;
NSArray *results = [moc executeFetchRequest:request error:&error];
// NSSLog(@"Autoincrement fetch results: %@", results);
NSManagedObject *maxIndexedObject = [results lastObject];
[request release], request = nil;
if (error) {
NSLog(@"Error fetching index: %@\n%@", [error localizedDescription], [error userInfo]);
}
//NSAssert3(error == nil, @"Error fetching index: %@\n%@", [error localizedDescription], [error userInfo]);
NSInteger myIndex = 1;
if (maxIndexedObject) {
myIndex = [[maxIndexedObject valueForKey:idKey] integerValue] + 1;
}
return [NSNumber numberWithInteger:myIndex];
}
CoreDataオブジェクトの3種類の一意のID表現は次のとおりです。
NSManagedObjectID *taskID = [task objectID];
NSURL *taskUniqueURLKey = task.objectID.URIRepresentation;
NSString *taskUniqueStringKey = task.objectID.URIRepresentation.absoluteString;
!!!!注:上記の一意のキーをインデックスとして使用する場合は、使用する前にオブジェクトがコンテキストに保存されていることを確認してください。 NSManagedObjectIDクラスのAppleドキュメント:
- (BOOL)isTemporaryID; // indicates whether or not this ID will be replaced later,
such as after a save operation (temporary IDs are assigned to newly inserted objects
and replaced with permanent IDs when an object is written to a persistent store); most
IDs return NO
を見てみましょう: [[NSProcessInfo processInfo] globallyUniqueString]
。
Apple docs:プロセスのグローバルID。 IDには、ホスト名、プロセスID、およびタイムスタンプが含まれます。これにより、IDがネットワークで一意であることが保証されます。これは、IDを推測したくない場合に便利です。
データの一意の行に自動インクリメントされたIDを必要とするリモートデータベースと同期したい場合はどうでしょうか?必要に応じて、自動インクリメントされたIDを実装する方法はありますか。コアデータには必要ないことを理解していますが、リモートデータベースからデータをインポートし、再度アップロードして、IDが完全であることを確認する必要があります。
Swiftの@Lukasz回答の更新:
static func nextAvailble(_ idKey: String, forEntityName entityName: String, inContext context: NSManagedObjectContext) -> Int {
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: entityName)
fetchRequest.propertiesToFetch = [idKey]
fetchRequest.sortDescriptors = [NSSortDescriptor(key: idKey, ascending: true)]
do {
let results = try context.fetch(fetchRequest)
let lastObject = (results as! [NSManagedObject]).last
guard lastObject != nil else {
return 1
}
return lastObject?.value(forKey: idKey) as! Int + 1
} catch let error as NSError {
//handle error
}
return 1
}
このような状況ではこれが役立つと思います。
http://lists.Apple.com/archives/cocoa-dev/2006/Jul/msg01801.html maxExistingIDを取得できます。 SO新しいアイテムを保存する際にそれをインクリメントできます
コアデータは永続化フレームワークに使用され、このフレームワークは主キーを抽象化します。
各NSManagedObjectには、objectIDプロパティで使用可能な固有のキーが組み込まれています。
このIDは、関係を介してエンティティをリンクするために内部的に使用されます。 SQLで使用するのと同じように、主キーとして独自のIDを維持する必要はありません。
NSManagedObject.objectIDでいつでもIDを取得できます。 NSMananagedObjectContext.objectWithIdを使用したオブジェクトコンテキストの取得