If we take the two below entities as en example.
public class Person
{
public string Username {get;set;}
public string DisplayName {get;set;}
}
public class Worker:Person
{
public string Title {get;set}
public int SecurityId {get;set;}
}
When anyone first registers with this app, basic information would be captured and a Person would be created. Once an admin comes along, they may want to assign a role to this Person. Now Roles in the sense of Authorisation are not in question, there is a RoleProvider. However, if I make someone a worker, some additional details need to be captured. How those new details are best stored is what is in question.
I could have a WorkerProperties class with the fields and give Person --> Worker a 0.1->1 relationship.
I could have all the fields as part of Person and just fill in what is required. At runtime accessing the Persons role would be needed to work out what fields would be required.
I could create a Worker as shown above. Inheriting from Person. With this option there is the problem that the PK is the username registered with. I would need to somehow change the discriminator column generated by EF to essentially change the object type to Worker.
1 Answer 1
Is 'Worker' really a subtype? If you say 'yes', then that person can't become any other subtype of 'Person', as you can't change the type of an object / entity instance without recreating it and deleting the old one.
If it's not really a subtype, but really another 'Role' a person can take (and I have to say, 'Worker' really sounds like a role), use a role system, so model what a person can do as a separate entity.
The problem is equal to whether a Person should have subtypes like 'Employee' or 'Customer'. If you design it that way, an Employee can't become a Customer. Well, in reality the Employee can of course, but in the DB it's not possible unless you create a new instance of Customer with the same data, which effectively copies the Employee entity instance.
-
To be fair, many tutorials on object design use exactly this kind of Worker:Person, Customer:Person, etc. subclassing. But your point that this is a bad choice that does not reflect the reality of the underlying situation is very well taken. And once this kind of mis-design is embedded at the foundation of a database or app, the number of convoluted fixes to work around this bad choice will only increase over time.Jonathan Eunice– Jonathan Eunice2014年08月15日 16:24:05 +00:00Commented Aug 15, 2014 at 16:24
-
Exactly the issues I want to avoid. Although I was considering that having the additional class with the 0.1:1 relationship could have its own issues.Lotok– Lotok2014年08月15日 16:50:40 +00:00Commented Aug 15, 2014 at 16:50
-
Yes. Primarily, complexity. Richer data model = more work to construct, more cases to consider, more cases to test, more variables when optimizing the underlying data store, etc.Jonathan Eunice– Jonathan Eunice2014年08月15日 21:54:27 +00:00Commented Aug 15, 2014 at 21:54