核心数据 - 使用相同的字段获取所有实体

时间:2017-12-12 11:35:04

标签: ios swift core-data

在我的ios swift应用程序中,我有一个使用Core Data的数据库。 它有许多实体,所有实体都有一个名为syncStatus的整数字段。它可以是0, 1, or 2

启动时,我想遍历所有syncStatus = 1的实体,并将其更改为0

有没有办法在不单独获取每种类型并更改它的情况下执行此操作?

所以我想要的是:

  • 使用ALL
  • 获取syncStatus = 1个实体
  • Loop通过它们并设置syncStatus = 0

目前我正在逐一完成这些工作:

  • 使用UserEntities
  • 获取syncStatus = 1
  • 循环浏览它们并设置syncStatus = 0
  • 使用countryEntities
  • 获取syncStatus = 1
  • 循环浏览它们并设置syncStatus = 0
  • 逐个为每个实体做同样的事情

let allUsers = context?.fetch(FetchRequest<UserEntity>().filtered(with: "syncStatus", equalTo: "1"))
let allCountries = context?.fetch(FetchRequest<CountryEntity>().filtered(with: "syncStatus", equalTo: "1"))
.
.
.

我只是想找到一个通用的方法,如果以后我们添加另一个实体/表格,我们不必回到这个代码并在此处添加它。

3 个答案:

答案 0 :(得分:2)

首先,获取所有条目并过滤它们比应用谓词要贵得多。

我建议使用静态方法的协议扩展。好处是您可以直接在类型

上调用方法
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sh = ss.getActiveSheet();
  sh.getRange(1,sh.getLastColumn()).activate();
  var data = sh.getDataRange().getValues();
  var today = new Date().setHours(0,0,0,0);
  for(var n=0;n<data.length;n++){
    var date = new Date(data[n][0]).setHours(0,0,0,0);
    if(date==today){
      Logger.log("FOUND n: " + n);
      break;
    };
  }

要使用它,对所有protocol SyncStatusResettable { associatedtype Entity: NSManagedObject = Self var syncStatus : String {get set} static var entityName : String { get } static func resetSyncStatus(in context: NSManagedObjectContext) throws } extension SyncStatusResettable where Entity == Self { static var entityName : String { return NSStringFromClass(self).components(separatedBy: ".").last! } static func resetSyncStatus(in context: NSManagedObjectContext) throws { let request = NSFetchRequest<Entity>(entityName: entityName) request.predicate = NSPredicate(format: "syncStatus == 1") let items = try context.fetch(request) for var item in items { item.syncStatus = "0" } if context.hasChanges { try context.save() } } } 子类采用SyncStatusResettable并调用

NSManagedObject

do { try UserEntity.resetSyncStatus(in: managedObjectContext) try CountryEntity.resetSyncStatus(in: managedObjectContext) } catch { print(error) } 是当前的managedObjectContext实例

答案 1 :(得分:0)

NSManagedObjectModel允许您枚举它包含的实体,NSEntityDescription可以为每个实体提供属性。一旦你有了对模型的引用:

let entitiesWithSync = model.entities.filter {
    $0.properties.contains(where: { $0.name == "syncStatus" })
}

将为您提供所有相关实体。然后,您可以使用此实体列表来推动更新 - 请注意,如果您在启动时执行此操作,则使用NSBatchUpdateRequest会更快。您可以使用上面循环中获取的实体描述创建批量更新请求。

答案 2 :(得分:0)

在过去,我已经从对象模型中循环遍历所有entitiesByName:

lazy var managedObjectModel: NSManagedObjectModel = {
    let modelUrl = NSBundle.mainBundle().URLForResource("SomeProject", withExtension: "momd")!
    return NSManagedObjectModel(contentsOf: modelUrl)
}

func updateAllData() {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext

    context.performAndWait {
        let allEntities = self.managedObjectModel.entitiesByName
        for (entity, items) in allEntities {
            let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
            ...
        }
    }
}