Answered by:
Inheritance problem in Entity Framework 4.0

Question
-
I am wondering if it is possible to create a derived entity even when no concrete db table exists for derived entity?
Idea here is to create a business layer that uses EF 4.0 for all CRUD operations and use T4 template and partial classes feature to write business logic in entities. In our current .NET 2.0 there are business classes that store data into database tables, There are cases when a second business class inherits base class and adds complex business logic. Database persistance logic stiil resides in base class. In nutshell Parent business class and derived business classes use same tables to store data.
We are considering writing application in .NET 4.0. I am wondering how can this be achieved in EF 4.0
thanks,
Abhishek
Monday, May 17, 2010 12:24 PM
Answers
-
You can use a derived type in EF4 without that derived type being in the model. For example, you could create an instance of AdvancedRecepieManagement, add it to the context, save it, and so on. The problem comes when you query for entities from the database. If there is no difference in the data for a RecepieManagement instance or a AdvancedRecepieManagement instance, then how would the EF know which type to create? In fact, it wouldn't, so it will always create instances of RecepieManagement because that is the only type it knows about.
This type of thing could theoretically be handled by allowing EF to use factory methods when it creates your entities. You could then hook up the correct factory method before doing the query and get AdvancedRecepieManagement objects for all your entities. Unfortunately, EF doesn't support this yet. Do you think that if you were able to specify to EF how to construct instances of your entities then this would cover your scenario? This would be useful information for the team to have.
Thanks,
Arthur- Proposed as answer by Arthur Vickers - MSFT Friday, May 21, 2010 5:12 PM
- Marked as answer by Michael Sun [MSFT]Microsoft employee Monday, May 24, 2010 8:21 AM
Thursday, May 20, 2010 4:59 PM
All replies
-
I would like to point out that there is no data diffrentiation. The way, it seems, that EF works is inheritance based on data diffrentiation. How to use EF 4.0 in scenario like this say there is an entity RecepieManagement and another derived Entity AdvancedRecepieManagement both pointing to same database table (Recipie). Both entities would expose same database properties. The diffrence, however, is that derived class AdvancedRecepieManagement would have extra properties (not database related) and some extra functions related to business logic.
Now a user need to create instance of RecepieManagement or AdvancedRecepieManagement based on his requirements.
Any idea, how this can be implemented in EF 4.0?
Abhishek
Tuesday, May 18, 2010 9:08 AM -
Hello Abhishek,
You could implement this with Table-per-Hierarchy inheritance. You only need one table (Recipie) in store model but generate two inherited entity according to the category. The extra properties (not database related) could be implemented using partial class as well as some extra functions.
We have a demo project here which deals with many table relationships in entity framework, you could download the project and open it in Visual Studio (it was created using VS2008). You could find the TablePerHierarchy folder and add your extra partial classes and functions. One example could be:
partial class Student { private String _myProperty; public string MyProperty { get { return this._myProperty; } set { this._myProperty = value; } } }
Best regards
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
If you have any feedback, please tell us.
Welcome to the All-In-One Code Framework!- Edited by liurong luo Thursday, May 20, 2010 8:08 AM format
Thursday, May 20, 2010 8:06 AM -
Hello Roahn,
Thank you very much for providing such a wonderful sample. I ran into build errors which I would try to resolve and run.
However, as I said, TPH works on data diffrentiation. In the sample TPH.edmx the derived entities Student, Instructor, Admin differ on data diffrentiation. So if one queries objectcontext for entities of type Student, records where PersonCategory=1 will be returned. So it is impossible to load records with PersonCategory = 2 in entity Student. (Am I correct here?)
On data side whole TPH logic seems okay but looking from business layer (aka POCO objects) perspective this is not always desired.
Let us consider our old POCO class Recepie, this class exposes all the methods and properties to handle the Recepie business logic and persists data into database using a separate DAL.
Now if someone wishes to extend functionality of Recepie he would inherit Recepie to create another class say AdvancedRecepie and add more complex business calculations and work on same set of data as Recepie object. This AdvancedRecepie does not add any separate DB persistance logic and base class handles DB persistance. So it was user's choice to create instance of AdvancedRecepie or Recepie based on functionality required.
I am wondering how can I handle this in EF 4.0 so as to avoid a separate business layer?
Thank you again for taking time to reply to this post.
Abhishek
Thursday, May 20, 2010 9:31 AM -
Yes, you are absolutely correct. You could query a specific entity by using OfType() operator, for example:
var student = from stu in context.People.OfType<Student>() select stu;
It only load entities of student type.
Best regards
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
If you have any feedback, please tell us.
Welcome to the All-In-One Code Framework!Thursday, May 20, 2010 10:32 AM -
I agree, but this is not what I am looking for. Let me put my question another way. How can I hydrate Student entity irrespective of what is value of PersonCategory column is. Suppose Person table contains say 100 records and I need to create instances of Student, Admin or Instructor based on my requirements. So if I query ObjectContext is there any way that all 100 records can be transformed into Student entity or Admin entity based on what user wants?
thanks,
Abhishek
Thursday, May 20, 2010 10:57 AM -
You can use a derived type in EF4 without that derived type being in the model. For example, you could create an instance of AdvancedRecepieManagement, add it to the context, save it, and so on. The problem comes when you query for entities from the database. If there is no difference in the data for a RecepieManagement instance or a AdvancedRecepieManagement instance, then how would the EF know which type to create? In fact, it wouldn't, so it will always create instances of RecepieManagement because that is the only type it knows about.
This type of thing could theoretically be handled by allowing EF to use factory methods when it creates your entities. You could then hook up the correct factory method before doing the query and get AdvancedRecepieManagement objects for all your entities. Unfortunately, EF doesn't support this yet. Do you think that if you were able to specify to EF how to construct instances of your entities then this would cover your scenario? This would be useful information for the team to have.
Thanks,
Arthur- Proposed as answer by Arthur Vickers - MSFT Friday, May 21, 2010 5:12 PM
- Marked as answer by Michael Sun [MSFT]Microsoft employee Monday, May 24, 2010 8:21 AM
Thursday, May 20, 2010 4:59 PM -
Hello Arthur
I tried the option of not making AdvancedRecepieManagement part of the model. I simply inherited AdvancedRecepieManagement from entity ReceipeManagement. However I was stuck and did not know how to make ObjectContext create instances of AdvancedRecepieManagement.
I completely agree that if EF expose a factory method or a way to override its filtering mechanism it would be great.
For example when user queries ObjectContext.RecepirManagementSet.OfType(Of AdvanceRecepirManagement) EF uses column diffrentiators to create appropriate instances. If user is able to hook in to EF filteration mechnism and able to override it this would make a great solution.
This way with the help of T4 class generators, developers can create extensible business classes, they do not have to worry about data persistance as EF would take care of it.
Many Thanks,
Abhishek
Friday, May 21, 2010 5:20 AM -
HI. 77
EF provides Table-per-Type Inheritance way maybe will help you .
below sliverlight video.
http://msdn.microsoft.com/en-us/data/cc765425.aspx
DON'T TRY SO HARD,THE BEST THINGS COME WHEN YOU LEAST EXPECT THEM TO.- Marked as answer by Michael Sun [MSFT]Microsoft employee Monday, May 24, 2010 8:21 AM
- Unmarked as answer by jainabhishek77 Tuesday, May 25, 2010 10:58 AM
Friday, May 21, 2010 1:14 PM