使用谓词查询核心数据

Posted

技术标签:

【中文标题】使用谓词查询核心数据【英文标题】:Querying Core data with predicates 【发布时间】:2016-12-21 07:25:46 【问题描述】:

所以我正在使用 CoreData 构建这个应用程序。

我拥有的两个实体是列表和项目。它们有一对多的关系,即一个列表可以有多个项目。

例如:List1 有 Items: item1, item2

我已经编写了将项目存储在特定列表中的代码,但我很难弄清楚如何从特定列表中获取和处理项目。

到目前为止我所做的如下

func getItemsOnList()

        let app = UIApplication.shared.delegate as! AppDelegate
        let context = app.persistentContainer.viewContext

        //fetchRequest to get the List
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "List")
        let predicate = NSPredicate(format: "title == %@", listName)
        fetchRequest.returnsObjectsAsFaults = false
        fetchRequest.predicate = predicate

        if let fetchResults = try? context.fetch(fetchRequest)
            if fetchResults.count > 0 
                for listEntity in fetchResults 
                    let list = listEntity as! List
                    print(list.title as Any)
                    itemsOnList = list.contains!
                    print(itemsOnList)
                    print("The list with name:\(list.title)has \(itemsOnList.count) items")

                
            
        
    

此函数返回一个 NSSet,它假定包含该特定列表中的所有项目。

我的数据模型是:

我的问题是:

A.我编写 getItemsOnList() 函数的方式是否正确?还是我做错了什么。

B.鉴于代码是正确的,并且我得到的 NSSet 对所有项目都是正确的,我将如何获取该 NSSet 中的每个项目以便将其放在 TableView 上。

【问题讨论】:

您可以使用MagicalRecord轻松处理核心数据任务。获取项目后,您有一个 Items 数组。您可以将此数组用作表格视图的数据源。除此之外,您可以creating a Fetched Results Controller 随时填充和更新表格视图。 【参考方案1】:
 func getItemsWithFilter(filterQuery:NSPredicate,sortBy:String?,order:Bool) -> Array<Items> 
var fetchedResults:Array<Items> = Array<Items>()


let fetchRequest = NSFetchRequest(entityName: "Items")
fetchRequest.predicate = filterQuery

if sortBy != nil
  let sortDescriptor = NSSortDescriptor(key:sortBy! ,
                                        ascending:order )
  let sortDescriptors = [sortDescriptor]
  fetchRequest.sortDescriptors = sortDescriptors


//Execute Fetch request you can go with your approach to
do 
  fetchedResults = try self.mainContextInstance.executeFetchRequest(fetchRequest) as! [Items]
 catch let fetchError as NSError 
  print("retrieveById error: \(fetchError.localizedDescription)")
  fetchedResults = Array<Items>()
catch 
  fetchedResults = Array<Items>()


return fetchedResults

要调用此方法,您可以将谓词中的列表项作为查询传递给 fetch Items in which List.id == XXX

 let predicate = NSPredicate(format: "ANY list.name in %@", name)
let myResult = self.getItemsWithFilter(predicate,sortBy:nil,order:false)

【讨论】:

我在 let fetchRequest = NSFetchRequest(entityName: EntityTypes.Items.rawValue) 时遇到错误 错误是使用了未解析的标识符“EntityTypes” 对不起,这是因为我的实体类型的自定义类.. 尝试用您的实体名称替换 EntityTypes.Items.rawValue,即“Items” 我不太明白最后该说什么关于在方法中传递什么?我假设一个谓词? 我收到这个未捕获的异常错误:2016-12-21 10:23:19.833 GroceryList[57092:2099351] *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“未实现的 SQL 生成对于谓词:(“列表 1”中的任何 item.name)'【参考方案2】:

答案: 一)是的。您正在使用来自 fetch 的对象图。这是 Core Data 的主要功能。 B)要填充表格视图,您不能使用集合。您需要某种排序的元素列表。也就是一个数组。使用 -orderedArrayUsingDescriptors: 获取排序后的数组。

【讨论】:

以上是关于使用谓词查询核心数据的主要内容,如果未能解决你的问题,请参考以下文章

核心数据 - 多对象谓词

作为获取谓词的日期范围 - 核心数据之间的 NSDate 谓词

核心数据 - 使用谓词更好地搜索

在核心数据谓词中为元素名称使用变量

核心数据:谓词中的对象

核心数据子查询:没有这样的列