限制核心数据中实体一对多关系的结果数量

问题描述 投票:0回答:3

我在核心数据中有以下对象图。

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
不能用于限制交易。

如何限制关系中对象的数量?

ios swift core-data nsfetchedresultscontroller nsfetchrequest
3个回答
0
投票

您无法使用

NSFetchRequest
解决此问题,也无法使用
NSFetchedResultsController
解决此问题,但解决方法是在 Account 上添加一个计算属性,以返回 10 个最新交易。

var sortedTransactions: [Transaction] {
    Array(transactions
        .sorted(using: KeyPathComparator(\Transaction.date, order: .reverse))
        .prefix(10))
}

0
投票

使用

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))
    }
}

实现此目的的另一种方法是发出多个获取请求来检索事务:

  1. 加载与帐户关联的所有对象 ID:
let idsFetchRequest = NSFetchRequest<NSManagedObjectID>(entityName: "Account")
idsFetchRequest.resultType = .managedObjectIDResultType
let ids = try! context.fetch(idsFetchRequest.resultType)
  1. 使用获取请求为每个账户获取 10 笔最新交易:
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)
}

如果您需要账户对象,您可以从交易对象中检索它。


0
投票

您可以使用 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;
© www.soinside.com 2019 - 2024. All rights reserved.