简体   繁体   中英

How do I count relationships with a particular column value from an NSFetchRequest?

I currently have 2 entities:

  • List
  • Item

This is a one-to-many relationship, in which a List can have many Items.

Items have a column called completed .

I want to obtain the count of a Lists completed Items from my NSFetchRequest.

I know that I can simply do List.Items.count to obtain a count of ALL of a Lists Items, but I've no idea how to get the count of completed items as well.

How do I count relationships with a particular column value from an NSFetchRequest, or even some type of filter/where of List.Items.count ?

Edit

I had to rename List to MyList and Item to MyItem .

  • MyList -> MyItem is one-to-many in Core Data (so I can use myList.myItems in the fetched results)
  • MyItem -> MyList is many-to-one in Core Data (so I can use myItem.myList in the fetched results)

Here is how I fetch the data. First I use an extension:

extension MyList {
    static func getAllMyLists() -> NSFetchRequest<MyList> {
        let request: NSFetchRequest<MyList> = MyList.fetchRequest()
        let sortDescriptor = NSSortDescriptor(key: "sortOrder", ascending: true)

        request.sortDescriptors = [sortDescriptor]

        return request
    }
}

Then I use a @FetchRequest in the view struct:

@FetchRequest(fetchRequest: MyList.getAllMyLists()) var myLists: FetchedResults<MyList>

Like I said I have no clue how to add the predicate I want to this so that the results include a count of the completed MyItems ...I'm using a terrible approach in my answer by not utilizing the fetch request to its full potential due to lack of knowledge.

dahiya_boy and Joakim were both right in the comments, I had to use an NSPredicate with filtered :

let completedPredicate: NSPredicate = NSPredicate(format: "completed == true")
let completedCount = List.Items.filtered(using: completedPredicate).count

There are two ways:

  • If you have the reference to the List object just filter the NSSet relationship

    let numberOfCompletedItems = (list.items as. Set<MyItem>).filter{$0.completed}.count

    You can avoid the forced type cast if you declare the to-many relationship as native Set<MyItem>

  • Otherwise fetch the items and add the predicate to the fetch request

    • "TheList" is the name of the list. If there is no name attribute use something unique.
    • context is the reference to the managed object context
    • It's assumed that there is a inverse relationship list in MyItem

       let listName = "TheList" let request: NSFetchRequest<MyItem> = MyItem.fetchRequest() request.predicate = NSPredicate(format: "list.name == %@ AND completed == true", listName) do { let completedItems = try context.fetch(request) let numberOfCompletedItems = completedItems.count } catch { print(error) }

And please name variables according to the naming convention starting with a lowercase letter

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM