Сложный предикат, не возвращающий результаты
Я застрял с этой проблемой некоторое время, и теперь я не могу придумать, как ее исправить. Я постараюсь объяснить это как можно яснее.
В моей основной модели данных есть 3 объекта. Рабочее место, пациент и передача.
На рабочем месте может быть несколько пациентов. Также пациент может принадлежать к нескольким рабочим местам.
Пациент может иметь одну передачу и наоборот.
В приложении список рабочих мест показывается пользователю. Когда пользователь выбирает рабочее место, мне нужно получить набор пациентов, которые принадлежат к этому выбранному рабочему месту и имеют на сегодня передачу обслуживания. Поскольку у пациента может быть несколько хэндоверов, для пациентов могут быть дубликаты записей, и это нормально.
Это то, что я делаю сейчас. Сначала я получаю объект Workplace для выбранного пользователя. Затем я перебираю его Patients, извлекаю идентификаторы объектов Patient и собираю их в массив. Затем я передаю массив идентификаторов пациентов и дату, чтобы отфильтровать пациентов, у которых есть передачи на указанную дату.
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
объект и получить его время начала и время окончания, чтобы получить рамку даты. Я использовал их в некоторых других местах, и они работают. Вот подробное объяснение об этом.
Во всяком случае мой 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 ответ
Используя граф объектов, это кажется действительно простым. Старайтесь избегать многословных запросов на выборку.
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))