NSP предикатный пример запроса отношения один ко многим - PullRequest
0 голосов
/ 24 августа 2018

Это моя основная модель данных

Соотношение следующее: введите описание изображения здесь

Отношения - это один маршрут ко многим локациям. Первый вопрос: должен ли быть атрибут name (routeName) в Location? Например, в DB2 вы всегда называете свои первичные ключи, но в большинстве примеров, которые я видел в Базовых данных, они обрабатывают первичные ключи под обложками в определении взаимосвязи.

Вот выдержки из таблицы из браузера БД для sqlite.

Выдержки из таблицы

Вот код:

    final class CoreDataManager {

static let sharedInstances = CoreDataManager()

let managedContext: NSManagedObjectContext

private init(){
    let application = UIApplication.shared.delegate as! AppDelegate
    managedContext = application.persistentContainer.viewContext
}


func createRoute(name: String) -> Route {
    let routeEntity = NSEntityDescription.entity(forEntityName: "Route", in: managedContext)!
    let route = NSManagedObject(entity: routeEntity, insertInto: managedContext)

    route.setValue(name, forKeyPath: "name")

    route.setValue(Date().timeIntervalSince1970, forKey: "ts")

    do {
        try managedContext.save()
    } catch let error as NSError {
        print("Could not save. \(error), \(error.userInfo)")
    }

    return route as! Route
}

func createLocation(loc: CLLocation, route: Route) {

    let locationEntity = NSEntityDescription.entity(forEntityName: "Location", in: managedContext)!
    let location = NSManagedObject(entity: locationEntity, insertInto: managedContext)

    location.setValue(loc.coordinate.latitude, forKeyPath: "latitude")
    location.setValue(loc.coordinate.longitude, forKeyPath: "longitude")
    location.setValue(loc.altitude, forKeyPath: "altitude")
    location.setValue(loc.timestamp, forKeyPath: "ts")
    location.setValue(route, forKeyPath: "route")

    do {
        try managedContext.save()
    } catch let error as NSError {
        print("Could not save. \(error), \(error.userInfo)")
    }
}

func getAllRoutes () -> [Route] {
    let routeFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Route")
    let routeResults = try! managedContext.fetch(routeFetch)
    return routeResults as! [Route]
}

func getLocationsByRoute (name: String) -> [Location] {
    let locFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Location")

    //select * from ZLOCATION, ZROUTE where ZLOCATION.ZROUTE = ZROUTE.Z_PK and ZROUTE.ZNAME = ?
    locFetch.predicate = NSPredicate(format: "locations.route = %@", name)
    locFetch.sortDescriptors = [NSSortDescriptor.init(key: "ts", ascending: false)]

    let locations = try! managedContext.fetch(locFetch)

    return locations as! [Location]
}

}

Если в Таблице расположений нет первичного ключа, как мне создать запрос, чтобы получить все Местоположения для данного Маршрута? Вы можете увидеть в коде, у меня есть метод getLocationsByRoute, но я не могу заставить запрос работать. Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 25 августа 2018
  • Если у вас есть объект Route, получите местоположения из свойства locations
  • Если вам нужно выбрать объекты, используйте формат предиката

    locFetch.predicate = NSPredicate(format: "route.name = %@", name)
    

    Путь ключа всегда <relationship name>.<attribute name> - в этом случае получают все Location объекты, чей name из связанного route равен заданному имени.

0 голосов
/ 25 августа 2018

Хватит думать в терминах базы данных, Core Data - это ORM.

Вы получаете все местоположения для маршрута, получая доступ к свойству locations класса Route, поскольку оно соответствует соотношению один ко многим между Route и Location

.
let locations = someRoute.locations
...