核心数据 - 使用同一字段获取所有实体
Posted
技术标签:
【中文标题】核心数据 - 使用同一字段获取所有实体【英文标题】:Core Data - Fetch all entities using the same field 【发布时间】:2017-12-12 11:35:03 【问题描述】:在我的 ios swift 应用程序中,我有一个使用 Core Data 的数据库。
它有许多实体,所有实体都有一个名为syncStatus
的整数字段。可以是0, 1, or 2
。
在启动时,我想遍历所有具有syncStatus = 1
的实体并将其更改为0
有没有办法在不单独获取每种类型并对其进行更改的情况下做到这一点?
所以我想要的是:
使用syncStatus = 1
获取ALL
实体
Loop
通过他们设置syncStatus = 0
目前我正在一一做:
使用syncStatus = 1
获取UserEntities
遍历它们并设置syncStatus = 0
使用syncStatus = 1
获取countryEntities
遍历它们并设置syncStatus = 0
对每个实体一个一个地做同样的事情
代码:
let allUsers = context?.fetch(FetchRequest<UserEntity>().filtered(with: "syncStatus", equalTo: "1"))
let allCountries = context?.fetch(FetchRequest<CountryEntity>().filtered(with: "syncStatus", equalTo: "1"))
.
.
.
我只是想找到一个通用的方法,以防以后我们添加另一个实体/表,我们不必回到这段代码并在这里也添加它。
【问题讨论】:
【参考方案1】:首先,获取所有条目并过滤它们比应用谓词要昂贵得多。
我建议使用带有静态方法的协议扩展。好处是可以直接在类型上调用方法
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()
要使用它,请为所有NSManagedObject
子类采用SyncStatusResettable
并调用
do
try UserEntity.resetSyncStatus(in: managedObjectContext)
try CountryEntity.resetSyncStatus(in: managedObjectContext)
catch print(error)
managedObjectContext
是当前的NSManagedObjectContext
实例
【讨论】:
真的很喜欢这个答案【参考方案2】:NSManagedObjectModel
允许您枚举它包含的实体,NSEntityDescription
可以为您提供每个实体的属性。一旦你参考了模型:
let entitiesWithSync = model.entities.filter
$0.properties.contains(where: $0.name == "syncStatus" )
会给你所有相关的实体。然后,您可以使用此实体列表来驱动更新 - 请注意,如果您在启动时执行此操作,则使用 NSBatchUpdateRequest
会更快。您可以使用上述循环中获得的实体描述创建批量更新请求。
【讨论】:
【参考方案3】:过去我已经遍历了对象模型中的所有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)
...
【讨论】:
以上是关于核心数据 - 使用同一字段获取所有实体的主要内容,如果未能解决你的问题,请参考以下文章
如何从核心数据中获取父实体的所有子实体,以及如何将父数据用作 UITableview