复合谓词不返回结果
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 <<---->> Patient <---->> Handover
这是假设移交与医院无关。如果他们这样做,您应该使用Handover
实体作为@DanK 建议的一种连接表:
Workplace <---->> Handover <<----> Patient
如果这是你想要的,谓词的应用会更短:
workplace.handovers.filteredSetUsingPredicate(
NSPredicate(format: "date > %@ && date < %@", startOfDay, endOfDay))
【讨论】:
谢谢。我不知道对象图查询。以上是关于复合谓词不返回结果的主要内容,如果未能解决你的问题,请参考以下文章
Core Data fetch 中的谓词返回的结果与数组上的相同谓词不同
CoreData:相同的谓词(IN)在保存操作后返回不同的获取结果