复合谓词不返回结果

Posted

技术标签:

【中文标题】复合谓词不返回结果【英文标题】:Compound predicate not returning the results 【发布时间】:2014-10-07 12:49:29 【问题描述】:

我被这个问题困扰了一段时间,现在我似乎想不出一种方法来解决它。我会尽量解释清楚。

我的核心数据模型中有 3 个实体。 工作场所患者移交

一个工作场所可以有多个患者。此外,Patient 可以属于多个 Workplace

患者可以进行一次交接,反之亦然。

在应用程序中,会向用户显示工作场所列表。当用户选择一个工作场所时,我需要获取一组患者,这些患者属于该所选工作场所并且今天有交接。由于患者可以进行多次移交,因此患者的记录可能重复,这没关系。

这就是我现在正在做的事情。首先,我检索所选用户的 Workplace 对象。然后我遍历它的患者并提取患者对象的 ID 并将它们收集到一个数组中。然后我传递患者 ID 数组和日期以过滤掉在给定日期有移交的患者。

let workplace = db.loadWorkplace(155) // 155 is the ID of the Workplace

var patientIDs: [Int] = []
for p in workplace.patients 
    let patient = p as Patient
    patientIDs.append(patient.id)

handovers = db.loadHandovers(patientIDs, date: NSDate.date())

这是des过滤的方法。

public func loadHandovers(patients: [Int], date: NSDate) -> [AnyObject] 

    let fetchRequest = NSFetchRequest()
    let entityDescription = NSEntityDescription.entityForName("Handover", inManagedObjectContext: managedObjectContext!)
    let patientPredicate = NSPredicate(format: "patient.id IN %@", patients)
    let datePredicate = NSPredicate(format: "date > %@ AND date < %@", getStartDate(date), getEndDate(date))

    let compoundPredicate = NSCompoundPredicate(type: .AndPredicateType, subpredicates: [patientPredicate, datePredicate])

    fetchRequest.entity = entityDescription
    fetchRequest.predicate = compoundPredicate

    var error: NSError?
    let result = managedObjectContext?.executeFetchRequest(fetchRequest, error: &error)
    return result!

getStartDate()getEndDate() 方法转换 NSDate 对象并获取其开始时间和结束时间以获取日期框架。我让它们在其他一些地方使用过,它们可以工作。 Here's详细解释。

无论如何,我的 loadHandovers() 方法返回 0 个结果。不可能,因为当我插入数据时,我可以看到今天的移交。下面是从核心数据执行的 SQL 查询。

SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZDATE, t0.ZSIGNEDBY, t0.ZSTATUS, t0.ZPATIENT 
FROM ZHANDOVER t0 
JOIN ZPATIENT t1 ON t0.ZPATIENT = t1.Z_PK 
WHERE ( t1.ZID IN  (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) 
AND ( t0.ZDATE > ? AND  t0.ZDATE < ?)) 

谁能告诉我我的谓词是否有问题?或者如果有不同的方法可以完全解决这个问题?我真的很感激。

谢谢。

【问题讨论】:

多对多关系被认为是糟糕的设计,并且您正在解决问题,因为您正在尝试解决此设计缺陷。考虑在 WorkPlace 和 Patient 之间引入一个桥接实体,将您的 M-M 关系转变为两个 1-to-M 关系。然后,您可以放弃现有的整个阵列解决方法,直接解决原始问题。 【参考方案1】:

使用对象图,这看起来很简单。尽量避免冗长的获取请求。

workplace.patients.filteredSetUsingPredicate(
  NSPredicate(format: "handovers.date > %@ && handovers.date < %@", 
              startOfDay, endOfDay))

您似乎对自己的设置有些困惑。如果一个病人只有一个Handover,为什么要用复数形式称呼关系handovers

矛盾的陈述说明了您的设置的另一个缺陷

“由于一个患者可以进行多次切换……”

在您的数据模型中,患者可以有一个交接,而不是很多。唯一的解释是您为同一患者维护多个Patient 实例,只是因为该患者有多个移交。这当然是不合逻辑的,也是您感到困惑和遇到错误的部分原因。

更好的数据结构,避免重复患者:

Workplace &lt;&lt;----&gt;&gt; Patient &lt;----&gt;&gt; Handover

这是假设移交与医院无关。如果他们这样做,您应该使用Handover 实体作为@DanK 建议的一种连接表:

Workplace &lt;----&gt;&gt; Handover &lt;&lt;----&gt; Patient

如果这是你想要的,谓词的应用会更短:

workplace.handovers.filteredSetUsingPredicate(
  NSPredicate(format: "date > %@ && date < %@", startOfDay, endOfDay))

【讨论】:

谢谢。我不知道对象图查询。

以上是关于复合谓词不返回结果的主要内容,如果未能解决你的问题,请参考以下文章

试图做一个复合谓词。不工作。

Core Data fetch 中的谓词返回的结果与数组上的相同谓词不同

快速,在具有复合谓词的提取结果控制器中找不到实体的键路径

CoreData:相同的谓词(IN)在保存操作后返回不同的获取结果

Core Data Fetch 在第二次使用谓词时返回 0 个结果

核心数据提取返回意外结果