Setting up relation to base model which has many classes that inheritate in Code First Entity Framework - entity-framework

I'm creating my db using code-first and entity framework. I'm defining all my models which works great, but now I have a Page class which can contain Blocks.
These Blocks have a base class with ID, BlockType, Position, Name etcetera but there are different types of blocks with different properties which are classes that inherit from this base class. I'm wondering how I can setup my models so the page can have a collection of 'blocks' without storing the custom properties in a comma seperated list or something like that.
Is it possible? And what is the 'good' way to model this..
Thanks in advance!

Entity Framework supports inheritance. There are various strategies to map your object model - base and derived classes - to a database schema. The most important are:
Table per hierarchy (TPH): Base class and all derived classes will be mapped to a single table in the database. Any custom properties of derived classes will appear as separate columns in the table and the table contains a discriminator column to distinguish between the types. EF manages to load the columns needed to materialize a specific type.
Table per type (TPT): The base class has its own table which only contains the base class properties. Every derived entity gets another table that has the additional properties of this type. EF manages to load the properties from the different tables (creating appropriate joins) that contain all properties to materialize a specific type.
TPT is - in my opinion - the cleaner approach to implement inheritance, but it currently (EF <= 4.3) has performance problems compared to TPH due to suboptimal SQL generated by EF. The problem will be solved in EF 5.0. But TPH will still remain the more performant way of mapping because it doesn't need to join multiple tables.
Benefits and drawbacks of the strategies are discussed in detail in the linked blog posts. In the blog you can also find the third (less often used) option - Table per concrete type (TPC).

Related

Dynamic Data Model in Entity Framework Core

I have a database model that can be modify by users at runtime:
adding new columns to existing tables
adding new tables
I want to use Entity Framework Core to access such model.
I'm able of creating the types for the new tables and fields using reflection but I'm not able of creating the DbSet members inside the DbContext class for these new types as the DbSet needs to know the type at compile time.
Does anyone know if this is something that can be achieved with EF Core?
A way of injecting the type to the DbSet member dynamically?
It sounds pretty weird to me that the users are the ones defining the tables and their columns, relationships, etc on runtime. Probably what you actually need is to have a structure of tables to support dynamic data, which is much more manageable, that is, a table that defines the UserModels, another table that defines the properties of those models, etc. That will vary a lot depending on your needs.
You could also consider using some special properties like XML data-type fields as suggested here: Dynamically adding a property to an entity framework object

model first table per concrete type (TPC) inheritance saves to both tables

trying to implement table per concrete type using model first, but when saving the derived type, EF saves to both the base and derived tables. how do you configure EF to save the type to the correct corresponding table?
There is a good discussion of choosing an approach here that recommends against TPC for Entity Framework: http://blogs.msdn.com/b/alexj/archive/2009/04/15/tip-12-choosing-an-inheritance-strategy.aspx
For this reason: While the EF runtime supports TPC, the designer doesn't, and using TPC in the EF forces you to avoid associations in your base type. Because of these issues we generally discourage the use of TPC with the Entity Framework.
My best guess is that if you are writing to a base and derived tables as your problem you have tried to implement this where you have a concrete class which is extended by an additional concrete class? As per the discussion above, the simple answer is TPC will not work like this for EF (the referenced article is 2009, but I don't think this has changed).

How to implement different types of a class: inheritance, interface or class property?

I need to implement the following but I'm not shure what the best way is:
I'm creating a message functionality for an MVC app.
There are two types of messages:
Public messages
Private messages
The only difference is that public messages have a ValidFrom and ValidTo date field. I have tried the following:
Method 1, interface
IMessage interface. Two classes PrivateMessage and PublicMessage that implements the interface. PublicMessage has the two extra properties. Mapped it to two different tables with entity framework.
Method 2, inheritance
Create a message base class that has all the fields. Create two classes that inherit the base class. Can map the message class to the db so I only have one table to keep the records. I cannot map an interface with EF Code First it seems.
Method 3, Enum property to set what type of message
public enum MessageType
{
Public = 1,
Private = 2,
}
I just have one Message Class, but add a field to show what type of message it is. Maps easily to one table, and easy to search for messages of type "Public". I have to make a mini wrapper around the enum becouse EF wont create a field in the db for it though.
Is really the two property fields enough to justify two different classes? Searching two database tables for unread messages is a bit ineffective?
Is there a right way to do this?
I use Entity Framework Code First 4.3.
ORM frameworks usually solve the inheritance problem in three ways :
1.One table for all objects: in this approach there's one table and each concrete class will use the same table . A discriminator will be used to find out which record is related to which class.
2.One table for each concrete object: for each concrete object there will be a corresponding table in the database and each object has its own map .The framework doesn't know that these objects are part of a inheritance hierarchy.(no discriminator is needed)
3.One table for each object (concrete or abstract):in this approach shared data is stored in a table that's map to the base abstract class and each concrete object will have a separated table storing its own data and there's a one to one relationship between this table and its parent table.Again a discriminator is needed in parent table to show the framework which records belong to which object.
in first approach number of tables is minimum (just one table) but it has all the fields of all objects . thus all uncommon fields should be nullable and can accpet null.
in second shared data is distributed among many tables but each table is in control of its own fields thus there's no need to have some unnecessary null values.
The third approach has the most number of tables the shared data is stored in one place and again there's no unnecessary null values all over the place.
It seems that according to your scenario the first approach is the best because the difference between two objects is very small (only two fields) and having some null values in your table is tolerable and it's better than having two or three tables in your database,
You can accomplish this is many ways, as it seems that you are experimenting with. So...
1) You can have 1 entity Message that contains all fields and an extra column IsPublic
2) You can have 2 entities PublicMessage and PrivateMessage persisted in 2 tables
3) You can have TPT or TPH inheritance model where you have Message as a base class of PublicMessage and PrivateMessage
The question of which to use is more about what business problem you are trying to solve. You mention that searching two tables is inefficient. So, I assume that you have a view to build where a single person can see both private and public messages. If you can, it is better to optimize after you have a performance issue (and data to support it).
It is interesting that the public messages have a to and from date. This suggests that the life cycle of the two entities differ. This could indicate that they need to be managed separately.
With all those assumptions, I would opt for the simple and make them to separate entities. Making two queries for unread messages is not the end of the world.

POCO entity without some fields (Free modeling of the entities)

I understand that, when working with POCO entities, you should work against your model (POCO Entities). Also I supose that part of the benefits of programming against models like those should provide benefits like defining classes that don't match exactly what you see in the db.
However, there are simple operations that I don't know how to do and that I assume they should be possible. For example, in some scenarios it can be useful to change the name of one column (atribute in the entity). Also I would like to know if it's possible to generate POCO models that only represents some fields of the table that supports the object in the db.
Is there any documentation about this kind of operations?
¡Thanks a lot!
POCO entity is just mapped class. The model in your question means mapping. The point of mapping is to define map between class and database table including mapping between properties and columns. So you can have different property and column names as long as it is correctly configured in mapping.
So if you are using EDMX file (designer) for generating the mapping you can simply change the name of property or entity and it will be reflected in your generated POCO entity. Also EDMX file will correctly update mapping. If you are using code first you must manually define mapping either through data annotations or through fluent API.
Entity should represent single data structure persisted to the database. Because of this each table can be mapped only once. Moreover EDMX designer demands that each non-nullable column without default value must be mapped to the entity. POCO generator is not tool for generating your different data views. What you are looking for is called projection. There are ways how to include mapped projections in EDMX file (DefiningQuery and QueryView) but both requires manual modifications of EDMX file and the first one also requires manual maintenance of EDMX file.
If you need to remove some properties from entity just to improve some query or because you don't need all data for some operation you can always use projection to anonymous or custom class directly in the query.
var query = from x in context.XEntities
select new XView
{
A = x.A,
B = x.B
};
POCO generator is only tool for generating classes for mapped entities and projections not for generating all data related classes you will ever need.

Any decent resources on how to map complex POCO objects in EF 4.1?

So I heard L2S is going the way of the dodo bird. I am also finding out that if I use L2S, I will have to write multiple versions of the same code to target different schemas even if they vary slightly. I originally chose L2S because it was reliable and easy to learn, while EF 3 wasn't ready for public consumption at the time.
After reading lots of praises for EF 4.1, I thought I would do a feasibility test. I discovered that EF 4.1 is a beast to get your head around. It is mindnumblingly complex with hundreds of ways of doing the same thing. It seems to work fine if you're planning on using simple table-to-object mapped entities, but complex POCO object mapping has been a real PITA. There are no good tutorials and the few that exist are very rudimentary.
There are tons of blogs about learning the fundamentals about EF 4.1, but I have a feeling that they deliberately avoid advanced topics. Are there any good tutorials on more complex mapping scenarios? For instance, taking an existing POCO object and mapping it across several tables, or persisting a POCO object that is composed of other POCO objects? I keep hearing this is possible, but haven't found any examples.
Disclaimer: IMO EF 4.1 is best known for its Code-First approach. Most of the following links point to articles about doing stuff in code-first style. I'm not very familiar with DB-First or Model-First approaches.
I have learned many things from Mr. Manavi's blog. Especially, the Inheritance with code-first series was full of new stuff for me. This MSDN link has some valuable links/infos about different mapping scenarios too. Also, I have learned manu stuff by following or answering questions with entity-framework tags here on SO.
Whenever I want to try some new complex object mapping, I do my best (based on my knowledge about EF) to create the correct mappings; However sometimes, you face a dead end. That's why god created StackOverflow. :)
What do you mean by EFv4.1? Do you mean overhyped code-first / fluent-API? In such case live with a fact that it is mostly for simple mapping scenarios. It offers more then L2S but still very little in terms of advanced mappings.
The basic mapping available in EF follows basic rule: one table = one entity. Entity can be single class or composition of the main class representing the entity itself and helper classes for set of mapped fields (complex types).
The most advanced features you will get with EF fluent-API or designer are:
TPH inheritance - multiple tables in inheritance hierarchy mapped to the same table. Types are differed by special column called discriminator. Shared fields must be in parent class.
TPT inheritance - each type mapped to the separate table = basic type has one table and each derived type has one table as well. Shared fields must be defined in base type and thus in base table. Relation between base and derived table is one-to-one. Derived entities span multiple tables.
TPC inheritance - each class has separate table = shared fields must be defined in base type but each derived type has them in its own table.
Entity splitting - entity is split into two or more tables which are related by one-to-one relation. All parts of entity must exist.
Table splitting - table is split into two or more entities related with one-to-one relation.
Designer also offers
Conditional mapping - this is not real mapping. It is only hardcoded filter on mapping level where you select one or more fields to restrict records which are allowed for loading.
When using basic or more advanced features table can participate only in one mapping.
All these mapping techniques follow very strict rules. Your classes and tables must follow these rules to make them work. That means you cannot take arbitrary POCO and map it to multiple tables without satisfying those rules.
These rules can be avoided only when using EDMX and advanced approach with advanced skills = no fluent API and no designer but manual modifications of XML defining EDMX. Once you go this way you can use
Defining query - custom SQL query used to specify loading of new "entity". This is also approach natively used by EDMX and designer when mapping database view
Query view - custom ESQL query used to specify new "entity" from already mapped entities. It is more usable for predefined projections because in contrast to defining query it has some limitations (for example aggregations are not allowed).
Both these features allow you defining classes combined from multiple tables. The disadvantage of both these mapping techniques is that mapped result is read only. You must use stored procedures for persisting changes when using these techniques.