我在核心数据中有以下对象图。
Account
实体与Transaction
具有一对多关系。它被指定为有序集。
我使用
NSFetchedResultsController
在分组表格视图中显示帐户列表及其交易记录。当我获取实体时,我只想获取最后 10 个交易。
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Account")
let sortDescriptor = NSSortDescriptor(key: "name", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
resultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: CoreDataManager.shared.persistentContainer.viewContext, sectionNameKeyPath: "name", cacheName: nil)
resultsController?.delegate = self
do {
try resultsController?.performFetch()
} catch {
print("Failed to create NSFetchedResultsController: \(error.localizedDescription)")
}
由于
NSFetchRequest
用于获取 Account
对象,因此 fetchLimit
不能用于限制交易。
如何限制关系中对象的数量?
您无法使用
NSFetchRequest
解决此问题,也无法使用 NSFetchedResultsController
解决此问题,但解决方法是在 Account 上添加一个计算属性,以返回 10 个最新交易。
var sortedTransactions: [Transaction] {
Array(transactions
.sorted(using: KeyPathComparator(\Transaction.date, order: .reverse))
.prefix(10))
}
使用
NSFetchedResultsController
是不可能做到的。
您可以将计算属性添加到您的
Account
模型中来表示最新交易的计数:
@objc(Account)
public class Account: NSManagedObject {
@NSManaged public var name: String?
@NSManaged public var transactions: Set<Transaction>?
var latestTransactions: [Transactions] {
guard let transactions else { return [] }
return Array(transactions
.sorted(by: { $0.date > $1.date })
.prefix(10))
}
}
实现此目的的另一种方法是发出多个获取请求来检索事务:
let idsFetchRequest = NSFetchRequest<NSManagedObjectID>(entityName: "Account")
idsFetchRequest.resultType = .managedObjectIDResultType
let ids = try! context.fetch(idsFetchRequest.resultType)
for id in ids {
let predicate = NSPredicate(format: "account == %@", id)
let fetchRequest = NSFetchRequest<Transaction>(entityName: "Transaction")
let sortDescriptor = NSSortDescriptor(key: "date", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.fetchLimit = 10
fetchRequest.predicate = predicate
// Retrieve the 10 most recent transactions for the associated account
let transactions = try! container.persistentContainer.viewContext.fetch(fetchRequest)
}
如果您需要账户对象,您可以从交易对象中检索它。
您可以使用 fetchOffset 和 fetchLimit:
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Account")
let sortDescriptor = NSSortDescriptor(key: "name", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
// for 1st time first request
fetchRequest.fetchOffset = 0;
fetchRequest.fetchLimit = 10;
// for 2nd time second request
fetchRequest.fetchOffset = 10;
fetchRequest.fetchLimit = 10;