试图理解核心数据关系或处理重复

Posted

技术标签:

【中文标题】试图理解核心数据关系或处理重复【英文标题】:Trying to understanding Core Data relationships or handling duplicates 【发布时间】:2012-06-11 17:26:43 【问题描述】:

我正在尝试验证我是否了解核心数据关系和/或可能如何处理重复项。

在下面的示例中,我的实体 Account 与实体 Transaction Date 存在一对多关系。我在想很多人,因为一个帐户下会有多个日期。

我感到困惑的是,我只想有一个特定的日期......意思是,只有一个日期,没有重复。然后,意图是使实体交易日期与实体事件具有一对多关系。因此帐户 XYZ 将具有 06/11/2012 的交易日期和实体事件的多个条目。那么账户 XYZ 将有 06/12/2012 的交易日期和实体 Event 的多个条目。

Account 和 Trans Date 之间的关系真的是一对多还是一对一? 如果是一对多...如何处理重复项?如何在实体 Trans Date 中只保留一个日期?如果我的代码通过条目添加到事件和交易日期中,是否在那里进行了一些处理?如何?

我猜测 Account to Trans Date 应该是一对一的...但目前还不确定。

/-----------------------\          /----------------------\       /------------------\
| Account               |          | Transaction Date     |       |   Event          |
|-----------------------|          |----------------------|       |------------------|
| name                  |          | addDate              |       |  amount          |
| balance               |          |                      |       |                  |
|-----------------------|          |----------------------|       |------------------|
| heldByAcct            | <-\      |                      |       |                  | 
|                       |     \->> | inAcct               |       |                  |
|                       |          | heldByEvent          |<-\    |                  |
\-----------------------/          \----------------------/   \->>| inTrans          |
                                                                  \------------------/

【问题讨论】:

【参考方案1】:

我不确定我是否理解您想要达到的目标,但我会尽力给您一些建议。

第一

如果Account 只能有一个Transaction Date,我认为你应该设置一对一的关系。通过这种方式,您可以确定一个Account 有一个Transaction Date,反之亦然。在后面,Core Data 会设置你的数据库,这样你的Account 表就会有一个对应的Transaction Date 对象的ID 字段。

第二

如果您正在设置结帐机制并且Account 可以进行多笔交易(例如每天只有一笔),您需要设置一对多的关系。如果您需要每天检查单笔交易,则需要手动执行检查。使用特定Account 和日期的谓词设置针对Transaction Date 的请求,并查看计数是否大于1。如果没有,请添加 Transaction Date

NSInteger count = [fetchRequest countForFetchRequest:&error]; // query against `Transaction Date`
if(count >= 1) // not allowed
else // allowed

通常当我需要检查重复项时,我使用 guid 作为实体的属性(例如 NSString 类型的 guid)。因此,在您的Transaction Date 中,您可以使用这样的机制。然后您可以使用如下谓词设置获取请求:

[NSPredicate predicateWithFormat:@"guid == %@ AND inAcct == %@", @"12345", [self currentAccount]];

每次插入新的Transaction Date 时,您都可以根据日期(没有时间)和特定的Account 生成一个新的 guid(使用您自己的协议来执行此操作)。

考虑一下,您还可以保存并检查没有时间部分的日期 (category-on-nsdate)。我认为它会起作用,但你需要尝试。通过这种方式,您可以简单地使用没有指导的谓词。例如:

[NSPredicate predicateWithFormat:@"addDate == %@ AND inAcct == %@", [self currentDate], [self currentAccount]];

希望对你有帮助。

【讨论】:

想想支票簿登记... 在银行 xxxx(帐户)下,日期为 06/11/2012(交易日期),我有很多条目(事件)。然后帐户 xxxx,日期 06/12/2012 我有更多条目。我已经尝试过帐户和交易日期之间的一对一关系,但是当我添加两个或更多事件时,我会根据交易日期检查 fetchrequest 计数,它不止一个。我只想要 2012 年 6 月 11 日的对象。抱歉描述不好。我可能并没有完全理解这是如何工作的。 您需要按照我在第二种方式中的建议手动检查它(我有一个编辑来区分两种不同的解决方案)。此外,您可以提供用于添加事件的代码,也许我可以帮助您。 不,不...我只需要验证并朝着正确的方向前进。我真的很感谢长长的回答,我理解你所展示的概念。我是一名使用旧语言的程序员并且知道键控数据库,但我不确定我是否误解了 Core Data 的工作原理。如果我被卡住了,我会再回来的!【参考方案2】:

要对事务寄存器进行建模,我建议将 addDate 设为 Event 的属性并完全删除 Transaction Date。

它显着简化了管理对象图所需的工作,并且无需对日期进行重复数据删除。

如果您需要生成唯一日期列表,您可以使用 distinctUnionOfSets 即时执行此问题的答案中所述: CoreData get distinct values of Attribute.

【讨论】:

哦,太好了!我制作交易日期的原因是能够将日期放在表格视图中的部分中。认为我可以从实体事务日期获取对象计数来设置 nubmerOfSectionsInTableView。 distinctUnionOfSets 可能吗? 由于您也需要表格视图的值,您可以在结果 NSSet 上调用 count 来获取计数。但是,是的,如果需要,您可以使用 @count.addDate 单独执行计数。 好点...我很抱歉,因为我对此很陌生。在某些时候,我想了解我的示例将如何工作,但我认为将 addDate 移动到 Event 会使它更简单,如您所说。我最初是这样的,但我想我必须这样做才能计算表格视图中的标题部分才能工作。每一步都是一次学习体验! 听起来你正在接受它。没有必要道歉。 我已经按照说明更改了模型...得到错误:“valueForUndefinedKey:实体帐户与键“@distinctUnionOfSets”的键值编码不兼容 NSSet *uniqueName = [account valueForKeyPath: @"@distinctUnionOfSets.addDate"];

以上是关于试图理解核心数据关系或处理重复的主要内容,如果未能解决你的问题,请参考以下文章

将对象插入核心数据实体时处理重复项

具有现有关系奇怪问题的核心数据插入[重复]

Cocoa:如何避免核心数据重复关系?

从具有实体之间关系的核心数据中获取数据[重复]

试图理解 LINQ [重复]

核心数据一对多关系在获取新对象后失去关系[重复]