SQL 从核心数据中输入获取请求

SQL type fetch request from core data

虽然也有类似的话题,但是stack overflow中的issue并没有明确的答案,我将在下面描述。为简单起见,我将简化实体。所以:核心数据中有两个实体:

第一个名为 Person 的实体具有以下属性:
名字
姓氏
城市

第二个实体:国家/地区,具有属性:
城市
首都

想法是,在一个视图控制器中,用户通过表单为第二个实体添加值——为国家/地区填写城市和首都信息。 在其他视图控制器中,用户填写名字和姓氏,但从已经从其他视图控制器中添加的数据填充的选择器视图中选择城市。

在第三个视图控制器中,我想获取第一个为其添加大写字母的实体(table 视图控制器中的所有信息),例如如果第一个实体包含数据:
John |琼斯 |芝加哥
第二个默认情况下应该有一行包含以下数据:
芝加哥 |华盛顿

如何将 "Washington" 分配给 "John"?

类似这个问题,但没有明确答案:Selecting columns from different entities

我想出了下一个数据库方案:

Entity:
    City
      Attributes:
        id: Integer 16
        name: String
      Relationships:
        [o] capitalOfCountryOptional: Country, inverse: capital
        [o] country: Country, inverse: cities
        [m] people: Person, inverse: city

    Country
      Attributes:
        id: Integer 16
        name: String
      Relationships:
        [o] capital: City, inverse: capitalOfCountryOptional
        [m] cities: Person, inverse: city

    Person
      Attributes:
        id: Integer 16
        firstName: String
        flastName: String
      Relationships:
        [o] city: City, inverse: people

一旦你需要一些人的信息并且你知道 id:

现在您可以创建所有需要的对象并设置为关系:

let country = ... Ukraine
let city = ... Lviv
let capital = ... Kyiv
let person = ... John Doe

country.capital = capital
city.country = country
person.city = city

然后您需要保存您的上下文,然后您可以检索人员信息:

import CoreData
public class MOPerson: NSManagedObject {    
    static func getPerson(id: Int16) -> MOPerson? {
        let request: NSFetchRequest<MOPerson> = MOPerson.fetchRequest()
        request.predicate = NSPredicate(format: "\(#keyPath(MOPerson.id)) = %@", NSNumber(int16: id))
        request.fetchLimit = 1
        let result: MOPerson? = (try? CoreDataController.shared.managedContext.fetch(request))?.first
        return result
    }
}

示例:

if let person = MOPerson.getPerson(id: 1) {
    print("Person: \(person.firstName), capital: \(person.city?.country?.capital?.name ?? "not defined")")
}