Сложный предикат, не возвращающий результаты

Я застрял с этой проблемой некоторое время, и теперь я не могу придумать, как ее исправить. Я постараюсь объяснить это как можно яснее.

В моей основной модели данных есть 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))
Другие вопросы по тегам