Khóa chính của dữ liệu cốt lõi


81

Điều này có vẻ ngu ngốc, nhưng tôi vẫn không thể tìm ra cách đánh dấu một thuộc tính làm khóa chính trong tệp xcdatamodel. Bộ nhớ liên tục của tôi là tệp sqlite. Ai giúp tôi với?

Trong trường hợp đó, làm cách nào để tôi có thể "xác thực" ID là duy nhất? Tôi có nên viết một phương thức xác nhận hay gì đó không?

Câu trả lời:


91

Tùy chọn của bạn là:

  • Sử dụng -[NSManagedObject objectID]. Lưu ý rằng ID này là tạm thời cho đến khi đối tượng được lưu lần đầu tiên hoặc bạn gọi-[NSManagedObjectContext obtainPermanentIDsForObjects:error:]
  • Sử dụng nhóm CFUUIDhàm để tạo UUID cho từng đối tượng trong -awakeFromInsertphương thức của bạn
  • Tạo hệ thống giống như khóa chính của riêng bạn để lưu trữ một số nguyên trong mô hình của bạn và tăng nó lên khi tạo từng đối tượng

Không có cách nào tốt để xác nhận rằng một thuộc tính là duy nhất. Điều gần nhất bạn sẽ nhận được là đảm bảo nó là duy nhất tại thời điểm tạo, sau đó triển khai phương pháp setter tùy chỉnh ngăn bất kỳ ai thay đổi ID.


5
Một câu trả lời mang tính xây dựng hơn nhiều - bạn nên được đánh dấu là giải pháp!
Grouchal

1
Tạo UUID là cách tốt nhất để thực hiện. Chúng tôi đang sử dụng nó trong ứng dụng của mình và nó đang hoạt động rất tốt.
object2.0

46

Hãy nhớ rằng Dữ liệu cốt lõi là một khung liên tục đồ thị đối tượng, không phải là cơ sở dữ liệu. Những thứ như khóa chính bị trừu tượng hóa vì chúng phụ thuộc vào việc triển khai lưu trữ liên tục.


2
Đây lẽ ra là câu trả lời mà @Mugunth nên chọn! Cảm ơn bạn đã hiểu biết của bạn.
Leonard

vậy liệu Core Data có tự tạo khóa chính không?
Nhà phát triển tiếp theo

24

Dữ liệu cốt lõi tạo khóa chính của riêng nó - bạn không cần phải thêm khóa. Bạn có thể lấy nó bằng

NSManagedObjectID *moID = [managedObject objectID];

14

đôi khi khi hack người ta cần số nguyên thực của khóa chính. đây là cách người ta có thể lấy nó:

NSManagedObjectID *yourManagedObjectID = [yourManagedObject objectID];
int yourManagedObject_PK = [[[[[yourManagedObjectID URIRepresentation] absoluteString] lastPathComponent] substringFromIndex:1] intValue];

mặc dù CoreData là một biểu đồ đối tượng, nếu người ta nhìn vào dữ liệu cơ sở dữ liệu SQLite do CoreData tạo ra, thì cách lấy khóa chính của NSManagedObject này sẽ không thành vấn đề. ii đã sử dụng CoreData và thư viện sqlite3 C cấp thấp cùng nhau trong cùng một mã và chuyển các khóa chính từ CoreData sang sqlite3 để tìm nạp các bản ghi hoạt động tốt.

! nếu Bạn định sử dụng mã này trong quá trình sản xuất, hãy lưu ý về những thay đổi nội bộ có thể xảy ra đối với cách khóa chính db chuyển đổi thành Bản trình bày URIR, nó có thể hãm mã của Bạn.

thưởng thức


1
Không có mối quan hệ nào được xác định giữa object-ID và SQLite RID. Có thể chỉ sử dụng được cho khóa tạm thời đối với phiên bản cụ thể, nhưng cách tiếp cận sai đối với Khóa chính liên tục vì nó có thể bị hỏng ở phiên bản khác một cách âm thầm.
eonil,

Chính xác thì ý bạn là gì khi "bị hỏng ở phiên bản khác"? tại sao khóa chính phải thay đổi?
manitu

Các giá trị PK sẽ không bị thay đổi, nhưng thuật toán tạo biểu diễn URL có thể bị thay đổi vì không có thuật toán nào được định nghĩa chính thức. Và trong trường hợp đó, mã của bạn không được đảm bảo trích xuất giá trị PK hợp lệ. (nếu bạn có bất kỳ nguồn nào xác định thuật toán, hãy cho tôi biết, sau đó tôi sẽ khuyên bạn đăng bài)
eonil 27/09/12

1
ĐỒNG Ý. đôi khi khi hack một phần là thuyết phục. Phiếu phản đối của tôi hiện đang bị khóa, vì vậy bạn thực hiện một số chỉnh sửa, tôi sẽ loại bỏ phiếu phản đối.
eonil

2
Vì lợi ích của tốc độ và hiệu quả, đôi khi sql là một cách để đi. Ví dụ của tôi, số lượng truy vấn nắm giữ (*), tổng, trung bình và nhóm. Đó là một ĐAU để làm trong OO, một dòng cho sql! 'Bản hack' đó hoạt động hoàn hảo và nếu Apple thay đổi nó, thì họ vẫn sẽ phải làm cho tham gia sql hoạt động theo một cách nào đó, vì vậy tôi đoán chúng ta vẫn ổn trong một thời gian;). Bỏ phiếu LÊN ngay cả khi về mặt lý thuyết chúng ta không nên làm điều này. Theo quan điểm của tôi, việc giấu hoàn toàn DB là một lỗi do các nguyên tắc gây ra nhiều hơn là các lý do kỹ thuật thực sự. Chúng tôi làm điều đó, lấy hàng loạt bằng SQL. mọi lúc trong nhiều hệ thống khác mặc dù có sẵn một khuôn khổ.
Eric Giguere

0

Nếu không hack NSManagedObjectID, bạn có thể thực hiện kiểm tra nhanh thuộc tính của mình trước khi quản lý việc thu thập dữ liệu từ xa.

Tôi đã tạo một phương thức tiện ích, hãy kiểm tra nó ở đây


0

Một tiện ích mở rộng Swift để truy xuất khóa chính

extension NSManagedObject {
    var primaryKey : String {
        guard objectID.uriRepresentation().lastPathComponent.count > 1 else { return "" }
        return objectID.uriRepresentation().lastPathComponent.substring(from: 1)
    }
}

Và đối với chuỗi

extension String
{
    func substring(from : Int) -> String {
        guard self.count > from else { return "" }
        return String(self[self.index(self.startIndex, offsetBy: from)...])
     }
}

-3

Tôi muốn sử dụng Thời gian + tên Lớp làm định danh duy nhất.


2
Không thực sự được khuyến khích, khi nào bạn có thể đảm bảo rằng không nhiều hơn một đối tượng được tạo cùng một lúc?
fat32

Không nên quá. Phương pháp này không thể đảm bảo khóa là duy nhất.
Cody

@Fynh Tôi không đăng mã và ya bài của tôi có thể chưa hoàn chỉnh, tôi luôn đồng bộ hóa phương pháp lấy thời gian.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.