如何从核心数据中获取父实体的所有子实体,以及如何将父数据用作 UITableview

Posted

技术标签:

【中文标题】如何从核心数据中获取父实体的所有子实体,以及如何将父数据用作 UITableview【英文标题】:How to fetch all childs from parent entity from core data, and how can i use the parent data as UITableview 【发布时间】:2019-05-16 07:07:18 【问题描述】:

我将父级设置为节,子级设置为节中的行数,但是在从每个父级获取子级时,只有一个子级的父级显示多个,我的代码是从核心数据中获取数据

var projectsArray: [Project] = []
var foldersArray: [Folders] = []

let fetchRequest = NSFetchRequest<Project>(entityName: "Project")
let sortDescriptor = NSSortDescriptor(key: "pname", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]

let fetchFolders = NSFetchRequest<Folders>(entityName: "Folders")
let sortDesc = NSSortDescriptor(key: "name", ascending: true)
fetchFolders.sortDescriptors = [sortDesc]
do 
    let newProjectArray = try managedContext.fetch(fetchRequest)
    projectsArray = newProjectArray
    for newObj in projectsArray
        if let projectId = newObj.id
            fetchFolders.predicate = NSPredicate(format: "pid = %@",projectId)
        
        do 
            foldersArray = try managedContext.fetch(fetchFolders)
            print("The folders are",foldersArray as Any)
        catch
    
catch let error as NSError 
    print("Could not fetch. \(error), \(error.userInfo)")
    projectsArray = []

在我的控制器中,我正在阅读,

func numberOfSections(in tableView: UITableView) -> Int 
    return (newProjectArray != nil) ? newProjectArray!.count : 0


func tableView(_ tableView: UITableView, numberOfRowsInSection
        section: Int) -> Int 
        if newProjectArray![section].isExpandable == true
            return (folders != nil) ? (folders!.count) : 0
        
        else
            return 0
        
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection
        section: Int) -> CGFloat 
        return 40
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath:
        IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier:
            "FoldersCell") as! FoldersCell
        if  newProjectArray![indexPath.section].isExpandable == true
            let folder  = folders![indexPath.row]
            cell.projectNameLabel.text = folder.name
        
        return cell
    

假设名为ABC 的项目包含一个folder,而项目XYZ 包含folder1,folder2,folder3,在显示单元格ABC 时它正在显示folder,folder1,folder2,folder3,而在显示单元格XYZ 时它正在显示folder,folder1,folder2,folder3,那么有什么好的解决方案。

【问题讨论】:

您是否在核心数据模型中的 Project 和 Folders 实体之间建立了关系? 是 Joakim,从项目到文件夹的一对可能关系 那么您不需要为文件夹单独执行提取,您可以直接在let projectFolders = project.folders 等代码中将它们作为属性访问。将 folders 替换为您在模型中命名的关系 我也尝试过使用它,遇到同样的问题代码是for newObj in projectsArray let new = newObj.mutableSetValue(forKey: "folder") let myObj = new.allObjects as? [Folders] for i in myObj! if newObj.isExpandable if newProjectArray.contains(newObj) foldersArray.append(i) 要发表评论的代码太多,我会发布一个答案。 【参考方案1】:

您不需要获取文件夹实体,因为您已经在项目和文件夹之间定义了由 Core Data 处理的一对多关系

let fetchRequest = NSFetchRequest<Project>(entityName: "Project")
let sortDescriptor = NSSortDescriptor(key: "pname", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]

do 
    let newProjectArray = try managedContext.fetch(fetchRequest)
catch let error as NSError 
    print("Could not fetch. \(error), \(error.userInfo)")

在其他代码中

func numberOfSections(in tableView: UITableView) -> Int 
    return (newProjectArray != nil) ? newProjectArray!.count : 0


func tableView(_ tableView: UITableView, numberOfRowsInSection
    section: Int) -> Int 
    if newProjectArray![section].isExpandable, let folders =  newProjectArray![section].folders  
        return folders.count
     
    else
        return 0
    


func tableView(_ tableView: UITableView, heightForHeaderInSection
    section: Int) -> CGFloat 
    return 40

func tableView(_ tableView: UITableView, cellForRowAt indexPath:
    IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier:
        "FoldersCell") as! FoldersCell
    if  newProjectArray![indexPath.section].isExpandable == true 
        if let folders = newProjectArray![indexPath.section].folders 
            folder = folders[indexPath.row]
            cell.projectNameLabel.text = folder.name
        
    
    return cell

以上代码已直接在网络浏览器中更改,未编译,因此可能不完全准确,但希望足以帮助您解决此问题

【讨论】:

嗨 Joakim,非常感谢,你救了我的命,太棒了

以上是关于如何从核心数据中获取父实体的所有子实体,以及如何将父数据用作 UITableview的主要内容,如果未能解决你的问题,请参考以下文章

使用 EF Core 保存附加实体时如何删除子实体

iPhone核心数据得到孙子

如何使用谓词过滤子实体集合?

核心数据父实体

从众多实体中恢复一个获取的实体——核心数据

获取核心数据中一对多关系的计数