【问题标题】:Swift iOS : Insert data into related entities in CoreDataSwift iOS:将数据插入CoreData中的相关实体
【发布时间】:2026-01-27 20:50:01
【问题描述】:

我试图理解在 CoreData 中的一对多关系实体中保存和检索记录的概念。我有两个表 Products (Master) 和 Sales (Details) 因此(一对多)关系,关系键是(sales)。

问题 1:注册产品销售时。我创建了 Sales 实体的实例,填充值,然后将其添加到 product.sales(关系)并尝试进行 managedObjectContext 保存。

第一个问题:我是否还必须将销售实体的实例输入到销售实体中?还是因为有关系会自动更新?

第二个问题:如果我想查询迄今为止发生的所有销售,我要查询销售实体吗?还是我查询产品实体中的关系?

感谢您的帮助!

tab images

【问题讨论】:

    标签: ios swift core-data


    【解决方案1】:

    第一个问题:我是否还必须将销售实体的实例输入到销售实体中?还是因为存在关系而自动更新?

    您可能没有意识到,通过将对象添加到managedObjectContext,您本质上是在保存对象。只要你做类似的事情

    let sale = Sale(context: managedObjectContext)
    

    紧随其后

    managedObjectContext.save()
    

    上下文向您的持久存储(您的实际 SQL 数据库)发出保存请求。

    因此,您是否还需要存储销售的问题已得到解答,它将始终在保存上下文时存储。

    第二个问题:如果我想查询迄今为止发生的所有销售,我要查询销售实体吗?还是我在 Products 实体中查询关系?

    这取决于...

    首先让我给你一点提示/最佳实践:

    始终确保建立反向关系

    Product 实体关系的核心数据编辑器中,您可以执行以下操作:

    您的销售关系如下所示:

    关系只不过是两个实体之间的依赖关系,因此两个实体之间总是存在反向关系,请确保如上所示将它们连接起来。

    我为什么要告诉你这个?记得我提到过,这取决于您查询的实体是什么?这是重要的地方。

    例如,如果您想要给定ProductSale,您将查询产品本身(通过查询其名为sale 的关系):

    let product = [A product instance from your Core Data store]
    let sale = product.sale // returns the sale the product is associated to
    

    如果您想要来自给定销售的所有产品,您可以利用products 关系查询Sale 实体:

    let sale = [A sale from your Core Data store]
    let products = sale.products // the products contained in the sale
    

    你提到你想要所有销售到给定日期

    为此查询Product 实体没有任何意义,因为每个产品只与它所包含的销售有关系。

    因此,要回答您的问题,您应该查询Sale 实体以检索给定日期的所有销售额。

    希望对您有所帮助,如果有不清楚的地方请告诉我。

    【讨论】:

    • 再次感谢@the_critic,我希望你有一些 youtube 教程,因为你真的很清楚地解释了事情。我正在创建一个个人应用程序来训练 coredata。它有 3 个选项卡(1:产品列表 / 2:购物车 / 3:销售历史)在 tab1 中您可以选择要购买的每种产品的数量,在 tab2 中显示所选商品的购物车,而 tab3 是您订单历史。所以我注意到,当我将商品添加到购物车时,它们甚至在我提交对数据库的更改之前就出现在订单历史记录中,并且我认为当我查询销售表时,我使用的是相同的 managedObjContext,就像你在你的解释中所说的那样。跨度>
    • 我还添加了一张图片供您查看,如果您注意到仅选择 4 种产品并添加少量数量(总共 8 种数量),我什至在保存之前就在订单历史记录中获得了 8 条记录。我只想显示之前下的订单。也许是 Products.sales 中的那些,但我如何从那里获取它们并填充表格视图并按日期排序。
    • 我认为您的问题是您拥有上次打开应用程序时的产品。每当您保存上下文时,数据都会保留在您的数据库中。如果您打开应用程序备份,您保存的产品仍然存在。您需要在适当的地方删除它们...
    • 不是这样,我认为您之前解释的创建该销售实体的实例并修改它是更新上下文而不是数据库,这就是为什么当我重新启动应用程序时我看不到这些记录。但我发现我在销售中添加了一个谓词设置关系键(产品)!= nil。现在我的问题是如何保存到 NSSet 对象中。有什么建议吗?
    • 我试过这个 (product.sales = NSSet(object: order);) 订单是销售的一个实例。当我尝试保存上下文时,我收到此错误 -> Error Domain=NSCocoaErrorDomain Code=1570 \"The operation could\U2019t be completed. (Cocoa error 1570.)\" UserInfo={NSValidationErrorKey=date, NSLocalizedDescription=The operation could not \U2019t 完成。 (可可错误 1570。),NSValidationErrorObject=
    【解决方案2】:
        let manageObjectContext = appDelegateObj.managedObjectContext
        let entity =  NSEntityDescription.entityForName("", inManagedObjectContext:manageObjectContext)
    let manageObj =  NSManagedObject(entity: entity!,insertIntoManagedObjectContext: manageObjectContext)
    manageObj.setValue("Mark Developer", forKey: "AttributeName")
            do {
                try manageObjectContext.save()
            } catch let error as NSError {
                print("Could not save \(error), \(error.userInfo)")
            }
    

    【讨论】:

      【解决方案3】:

      我需要进一步研究这个问题,因为我也仍然在研究 Core Data,但是在我找到时间去做之前,我认为可能对你有用的是:

      问题 1:也将销售输入到销售实体中。我不相信这会为你完成。关系真正变得重要的地方在于删除。您可以指定您希望他删除的规则是什么,无论是无效、拒绝、级联还是不执行任何操作。 Raywenderlich.com 有一个关于 Core Data 的优秀教程系列,可能会对您有所帮助。

      问题 2:我认为这取决于您要查找的数据存储在哪个表中(尽管在 CoreData 中该术语是 ManagedObject)。查询销售实体对我来说最有意义。如果您不想,则不必查询整个销售实体。您可以指定搜索参数。

      【讨论】:

        【解决方案4】:

        从 swift 3 开始,您不必创建在 Core Data 中创建的实体类的属性,因为 Core Data 会为您完成这些。不过,您确实必须初始化这些属性。人际关系也是如此。例如,在产品类(父级)的情况下,与销售(子级)的关系已经为您实例化了。因此,您可以通过获取 Product Class 中的关系实例来访问和设置实体销售。可能还有其他方法可以做到这一点,但我认为使用扩展非常酷。

        扩展产品{

        //只要您“导入 CoreData”,您就可以从程序的任何//部分调用此构造函数:Product(sale) //如果它是 1 个销售,那么 s 1-1 如果它大于 1 它是 1-many 便利初始化?(销售或销售){

            let MOC = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext
        
            self.init(context: MOC)
        
            //case 1 when sale is 1-many
            let sale = Sale(context: MOC)
        
            //case 2 when sale is many-many(this can be an array of objects that you sent)
        
            let sale1 = Sale(context: MOC)
            let sale2 = Sale(context: MOC)
            let sale3 = Sale(context: MOC)
        
            //setting sale  object
             sale.property = ""
        

        //现在是时候设置与刚刚设置的对象的关系了

            //case when is 1 - many
            self.sale = sale
        
            //case when is many - many
            self.sale?.adding(sale1)
            self.sale?.adding(sale2)
            self.sale?.adding(sale3)
        

        }

        现在您的产品将与您的销售相关......

        【讨论】: