领域模型包含属性,但在运行时找不到它



我收到如下错误

属性名称无效,原因:"在类型为"MyCustomModel"的对象中找不到属性'IsRecordDeleted'

我的模型在哪里

@objcMembers public class MyCustomModel : Object {
dynamic var   Id : String = ""
dynamic var   ProductId : String? = ""
dynamic var   IsRecordDeleted : Bool? = false
dynamic var   ProductBarcode : String? = ""

override public class func primaryKey() -> String? {
return "Id"
}

}

我正在进行这样的查询:

let mSavedItems = mDbHelper.realmObj.objects(MyCustomModel.self).filter("IsRecordDeleted = false")

这里可能有什么问题。我不知道为什么我的应用程序崩溃并出现相同的错误。但是如果我像

let mSavedItems = mDbHelper.realmObj.objects(MyCustomModel.self).filter("ProductId = 0")

该应用程序运行,但当我在谓词中使用IsRecordDeleted时崩溃。

请告诉我可能有什么问题

你可以试试

let mSavedItems = mDbHelper.realmObj.objects(MyCustomModel.self)
let filtered = mSavedItems.filter { $0.IsRecordDeleted == false }

let mSavedItems = mDbHelper.realmObj.objects(MyCustomModel.self) 
let filtered = mSavedItems.filter { $0.ProductId == "0" }

对于两者

let mSavedItems = mDbHelper.realmObj.objects(MyCustomModel.self) 
let filtered = mSavedItems.filter {
$0.IsRecordDeleted == false 
&& $0.ProductId == "0" 
}

//

let resultPredicate = NSPredicate(format: "ProductId == '0' AND IsRecordDeleted == false")
let filtered = mSavedItems.filter(resultPredicate)

我想你会发现简单地切换到过滤器块而不是字符串谓词可能会阻止崩溃,但不会产生预期的结果。

这是因为IsRecordDeleted永远不会保存到数据库中。它不是一个可以用 Objective-C 表示的类型,因此它不能被dynamic,所以 Realm 忽略了它。

以以下类为例:

@objcMembers class MyObject: Object {
dynamic var id = ""
dynamic var testBool: Bool? = false
override static func primaryKey() -> String {
return "id"
}
}

假设我们像这样初始化它们:

let obj1 = MyObject()
obj1.id = "1"
obj1.testBool = true
let obj2 = MyObject()
obj2.id = "2"
obj2.testBool = false
let realm = try? Realm()
try? realm?.write {
realm?.add(obj1, update: true)
realm?.add(obj2, update: true)
}

如果我们使用realm.objects(MyObject.self)在 Realm 中查询这些对象,你会得到这样的结果。

Results<MyObject> <0x7fe410c0ad90> (
[0] MyObject {
id = 1;
},
[1] MyObject {
id = 2;
}
)

你会看到在数据库中,确实没有名为testBool的属性,这是我们的可选Bool

您可以轻松看到,如果像这样写出可选Bool可能会导致问题:

class MyObject: Object {
@objc dynamic var id = ""
@objc dynamic var testBool: Bool? = false   // This line will not compile.
override static func primaryKey() -> String {
return "id"
}
}

我很好奇为什么IsRecordDeleted首先需要是可选的,因为它似乎从一开始就具有价值。如果没有,那么类似这样的事情将按预期工作:

@objcMembers public class MyCustomModel: Object {
dynamic var Id: String = ""
dynamic var ProductId: String? = ""
dynamic var IsRecordDeleted: Bool = false
dynamic var ProductBarcode: String? = ""

override public class func primaryKey() -> String? {
return "Id"
}
}

您可以通过字符串进行查询,就像您最初尝试的那样。

如果它必须是可选的,那么 Realm 会针对这种情况提供一个RealmOptional,你可以在这里查看。

最新更新