Is it possible to include Core Data entity type in constraint?

Viewed 341

I'm working with Core Data + Swift 4.2 + Xcode 10. In my data model, I have an abstract entity A which has no parent entity, entity B which has A as its parent, and C which has A as its parent.

Entity A has a timestamp field, which is therefore inherited by B and C. I would like to impose a constraint that timestamp must be unique within an entity type. That is, I want all B items to have unique timestamps, and all C items to have unique timestamps, but some B item might have the same timestamp as some C item.

Is there a way to express that constraint in Xcode? The "Constraints" field in the entity editor wants a list of attributes. Timestamp is an attribute, so that's OK, but the entity type (B or C) is not. So I don't see a way to include entity type.

Is it possible that entity type is an implicit attribute? Just a shot in the dark here.

EDIT: To be clear, the reason I'm asking is that I tried to save an instance of B with timestamp T1 and an instance of C with timestamp T1 also, and I got an error to the effect that the constraint was violated. I was hoping that both instances would be saved (perhaps that was wishful thinking on my part). I am working with the Sqlite backend if that makes a difference.

2 Answers

I don't think you can specify this behavior automatically in Core Data. But you can achieve this by adding another property to Entity A, and then making a constraint on the combination of that property and timestamp.

In this example, I added subtype to Entity A, and specified a constraint of subtype,timestamp.

enter image description here

These are the entity classes:

class EntityA: NSManagedObject {
    @NSManaged var timestamp: String
    @NSManaged var subtype: String
}
class EntityB: EntityA { }
class EntityC: EntityA { }

You need to set the subtype correctly before saving the entity:

entity.subtype = "B"

or

entity.subtype = "C"

or more generically:

entity.subtype = entity.entity.name!

It's not beautiful, but it works.

I just tried to do something similar. I ended up being able to do a switch statement with the property, and then use case is Entity:

switch variableEntity {
        case is EntityA:
            print("EntityA:")
        default:
            print("Default:")
        }
Related