-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TPH does not support immutable discriminator properties #4650
Comments
This will be enabled by our "Flexible mapping to CLR types and members" feature (#240). That would allow you to specify how the value is get/set from the property - allowing you to no-op the property set if you know it's going to be the right value.
Materialization code is very perf sensitive, so we don't do checks like this (they tend to slow things down a lot). |
BTW in the meantime the workarounds would be to add a field or add a private setter. |
If it's a perf-sensitive thing, why not skip the set altogether? That would be ideal for both perf and enforcing correctness. You don't want people relying on EF to set the discriminator value, so skipping the set would encourage better coding (= read only discriminator so that it can never conflict with the subclass type). |
The reason we set it is there is no guarantee that the entity is setting it to the right value itself (as yours does). It's one of those things where "the right thing to do" varies greatly depending on who you talk to, so we tend to leave it as flexible as any other property you would map to. To be clear, we definitely want to support your scenario (for more than just discriminator properties), it's just not done yet. |
Thanks for the clarification. I think the pit of success with mutable discriminators is to discourage them and to be strict checking them. I'm curious what the discussion has been so far (in what scenarios is a mutable discriminator necessary or a good design?), but since I won't have mutable discriminators in my code I won't care. I'll just wait until I don't need a private setter anymore and be happy. |
The default behavior with EF is to have discriminators as shadow properties... so there isn't even a property in your class at all. To me this makes the most sense, because there are already first class ways of reasoning about types in code ( |
That is an excellent point which I had not considered: simply leaving the discriminator column out of the model. I do not like the defaults because I do care about the database schema and byte enums are my favorite way of handling this. But with shadow properties I can have the best of both worlds.
Ironically, I'm using separate data and domain models. My domain model uses an enum with a value for each subclass as a sorting technique, since subclasses are sorted by date and type. So the entity (domain) model already has the enum, but for the relational (data) model I don't actually want the discriminator column on the model classes because it's redundant and meaningless on the relational model. |
I have the following model:
When loading from the database:
This should not be a problem. If EF cannot find a way to set the value of
Type
, it should simply compare it to see if it already equals the value it's trying to set. The value ofType
has already been taken into account by selecting theSubclass1
type.If the discriminator property is expressed in the CLR model, it would be unusual for a model not to initialize a discriminator property. Indeed it seems counter-intuitive for the model to allow the property to be mutable. For my case, there's no reason to add a backing field on every instance and add the possibility of data corruption when the value is known statically by the subclass. Even if the setter is available it may be better simply to skip the set, check the property value and throw an error if the constructor didn't initialize the property with the expected discriminator value.
Also, EF6 supports this scenario and it's a good precedent.
Full repro code.
(These issues look related but I don't think this is a duplicate.)
The text was updated successfully, but these errors were encountered: