是否可以在核心数据中使用带参数的计算属性?

问题描述 投票:0回答:1

这可能是一个奇怪的问题,因为我不完全了解瞬态和新派生的属性如何在Core Data中工作。因此,假设我有一个RegularClass实体,该实体存储随时间重复的任何类。例如,每三天或每星期重复一次课程。这就是它在数据模型中的样子:

data model for RegularClass

((RegularClass属于Schedule实体,而该实体又属于Course实体)

[现在,如果我们的类每三天重复一次,我们将数字3存储在frequency属性中,并将字符串"days"存储在unit属性中,然后在Swift中将其转换为枚举。每个Schedule所属的RegularClass具有startDate属性。

[要检查某个班级是否在给定日期发生,我想出的最好方法就是计算unit和给定日期之间指定的startDate的差,然后取差和频率之间的余数,如果它是0,而不是可以上课的日期。

var differenceComponent: Calendar.Component {
    switch unitType {
    case .weeks:
        return .weekOfYear
    case .days:
        return .day
    }
}

func getDifferenceFromDateComponents(_ dateComponents: DateComponents) -> Int? {
    switch unitType {
    case .weeks:
        return dateComponents.weekOfYear
    case .days:
        return dateComponents.day
    }
}

func dateIsInActiveState(_ date: Date) -> Bool {
    if let startDate = schedule?.startDate {
        let comps = Calendar.current.dateComponents([differenceComponent], from: startDate, to: date)
        if let difference = getDifferenceFromDateComponents(comps) {
            let remainder = Int64(difference) % frequency // that is the key!
            return remainder == 0
        }
    }
    return false
}

func containsDate(_ date: Date) -> Bool {
    if dateIsInActiveState(date) {
        if unitType == .days {
            return true
        }

        let weekday = Calendar.current.component(.weekday, from: date)
        return (weekdays?.allObjects as? [Weekday])?.contains(where: { $0.number == weekday }) ?? false
    }

    return false
}

现在,事情是这段代码非常适合我从获取请求中获得的课程。但是,是否有一种方法可以在请求发生时在NSPredicate中传递日期参数来进行计算?还是我必须获取所有课程,然后手动将其过滤掉?

swift core-data database-design nsmanagedobject transient
1个回答
0
投票

要解决此问题,您可以将数据存储为标量类型,然后在谓词中执行简单的算术运算。而不是日期,而应使用具有从零开始的天数(或这些计算所需的最小时间单位)的整数。将重复周期存储为天数。

然后您可以在谓词中使用计算((searchDate - startDate) mod repeatCycle) == 0查找匹配的类。

正如您所建议的,针对不同的搜索案例对数据进行非规范化可能是明智的。

© www.soinside.com 2019 - 2024. All rights reserved.