简体   繁体   中英

Data model for enum with associated values

I'm trying to figure out what's the recommended way to implement enum with associated values in Core Data data model. Let's say I have a book entity and I want to save in database how I got the book, like:

  • it's bought by me (or other family members)
  • it's borrowed from someone (eg, a colleague)
  • it's given as a gift by someone (eg, a friend)

This would be an enum in swift:

enum WhereItCameFrom {
    case Bought(who: String, date: Date, where: String)
    case Borrorwed(who: String, date: Date, dueDate: Date)
    case GivenAsGift(who: String, date: Date, forWhat: String)
}

I'm thinking to implement it in data model using inheritance , as below:

  • Introduce a parent entity WhereItCameFrom and define the above cases as its children entities.

  • Define a to-one relationship from Book to WhereItCameFrom . Its deletion rule is Cascade .

  • Define a to-one relationship from WhereItCameFrom to Book . Its deletion rule is Deny .

See the diagram:

在此处输入图片说明

I'm wondering if this this the right way to do it and I have a few specific questions.

1) What's the typical way to implement enum with associated values?

I think my above modal is good. But just in case, are there other better ways to do it?

2) Is entity with no attributes normal?

In above diagram, WhereItCameFrom doesn't have any attributes. At first I added a type attribute to it to indicate if it's a Bought , Borrowed , or GivenAsGift entity. But then I realized this information is implicit in its child entity class type, so I removed it. So the only purpose of the parent entity is to hold the relationship. Is this use typical in Core Data?

3) Will the old object be removed automatically when modifying relationship at run time?

Suppose I modify book.whereItCameFrom relationship value at run time. Its previous value is a Borrowed object. Its new value is a GivenAsGift object. Do I need to delete the Borrowed object manually (I mean, doing that explicitly in application code)?

I guess I should do it. But given Core Data is a framework helping to maintain data consistency in object graph, that seems awkward to me. I wonder if Core Data has some feature that can figure out the Borrowed object is not needed and delete it automatically?

Thanks for any help.

UPDATE:

In the third question, after the old Borrowed object is disconnected with Book object, is my understanding correct that, from the Borrowed object perspective, the peer object has been delete and hence the peer object's Cascade deletion rule is applied to the Borrowed object? If so, then it will be deleted automatically. I think the real question here is if deletion rule applies to relationship update or not. I'll do some experiments on this later today.

A few thoughts...

1) What's the typical way to implement enum with associated values?

I think my above modal is good. But just in case, are there other better ways to do it?

I can't comment on typical ways of implementing enums with associated values, but your model seems to make sense. One word of caution: if you search StackOverflow for questions regarding entity inheritance, you will find several answers advising against using it. The way CD implements subentities (at least for SQLite stores) is to add all the attributes of all the subentities to the parent entity SQLite table. That's handled for you "under the hood" by CoreData, but the SQLite table can potentially end up being very "wide", which can affect performance. I've never found it an issue, but you might want to have that in mind if you have lots of data and/or the entities are more complex than you indicate in the question. Subentities can also cause issues in some rare situations - for example, I've seen questions indicating problems with uniqueness constraints.

2) Is entity with no attributes normal?

It's unusual, but not a problem. However, as all three subentities have date and who attributes, it would be wise to move these from the subentities to the parent WhereItComeFrom entity. (Otherwise, as noted above, your parent entity table will have three columns for date (one for each subentity) and three for who ).

3) Will the old object be removed automatically when modifying relationship at run time?

No. If you modify the book.whereItCameFrom relationship value at run time, with a GivenAsGift object replacing a Borrowed object, CD's graph management will ensure that the Borrowed object's book property is set to nil. The cascade rule does not prevent objects being "orphaned" in this way and you must manually delete the Borrowed object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM