复合谓词不返回结果

时间:2014-10-07 12:49:30

标签: ios sql core-data nsfetchrequest nscompoundpredicate

我已经坚持这个问题一段时间了,现在我似乎无法想出一个正确的方法。我会尽可能清楚地解释它。

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

enter image description here

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

患者可以有一个移交,反之亦然。

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

这就是我现在正在做的事情。首先,我为所选用户检索Workplace对象。然后我遍历它的患者并提取Patient对象的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())

这是过滤的方法。

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 < ?)) 

任何人都可以告诉我,如果我的谓词有问题吗?或者,如果有不同的方法来完全解决这个问题?我真的很感激。

谢谢。

1 个答案:

答案 0 :(得分:1)

使用对象图,这看起来非常简单。尽量避免使用详细的获取请求。

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

您对自己的设置感到有点困惑。如果患者只有一个Handover,为什么要以复数形式称呼关系handovers

矛盾的陈述

说明了你的设置的另一个缺陷
  

“因为患者可以进行多次移交......”

在您的数据模型中,患者可以进行一次移交,而不是很多。唯一的解释是,您为同一患者维护多个Patient个实例,仅仅因为患者有多个移交。这肯定是不合逻辑的,也是你遇到混乱和错误的部分原因。

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

Workplace <<---->> Patient <---->> Handover

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

Workplace <---->> Handover <<----> Patient

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

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