In my application, I have an entity, say Customer which maps to Customer. This is working fine now.
Our plan is to provide our current project as a reference to another client project. The client project also has a Customer table, but with some additional columns. Creating another Customer entity in the client project throws the error saying "both types have simple names".
Can this be solved using inheritance. Or does EF allow us to create classes with different names and map it to same table, like Customer and CustomerClient both maps to Customer table, but CustomerClient has the additional columns added.
Edit: I will try to provide the code once I am in office.
It sounds like entity framework inheritance is what you are looking for,
and especially TPH (Table Per Hierarchy) which is the the way to implement inheritance in entity frameork where all derived entities mapped to the same table.
TPT (Table Per Type) is the other option where all dervied classes are mapped to their own tables beside the base class table.
If you are looking for more info about implementing TPH and you are using EF code first this a good link to start with, and if you are using the designer you can use this.
Here is a tutorial how to choose EF inheritance strategy.
Note: I did not mention the TPC (Table Per Concrete Class) strategy which is also described in this post becuase I do not think this is what you are looking for.
This is a great video lessons tutorials that cover EF inheritance using code first and the designer and much much more.
Hope it helps!
Related
I'm trying to understand Entity Framework Code First.
Is it possible to configure a many-to-many relationship without using fluent API but just DataAnnotation?
For example in this tutorial I don't understand if the two examples are the same thing but done in different ways or if they have to exist together.
If they are different ways for the same thing, what is actually the difference?
And if they have to coexist, what is the API "part" doing?
Indeed you are right.
This paragraph:
Configure Many-to-Many relationship using DataAnnotation:
Student class should have a collection navigation property for Course, and Course should have a collection navigation property for student,
is wrong. Because the many-to-many relationship in the sample code in created automatically by convention when you add a collection in each class. The only data annotation that is used is Required attribute which is not implied in the many-to-many relationship.
BTW the section about "Configure Many-to-Many relationship using Fluent API" is correct but in their sample code they use it only put a custom name to the foreign key in the join table instead of letting Code First generating it. Foreing key renaming can be done too with Data Annotation by using ForeignKey attribute.
They're two different ways of configuring the database. They can coexist, but they don't have to; you can use just one or the other. If you do use both, the Fluent API takes precedence over the data annotations, but the data annotations still take precedence over the default conventions.
The difference is that API allows a more exacting degree of control, in exchange for being (arguably) more complicated. The example you linked does show two different ways of accomplishing effectively the same thing, and you could use one or the other if you wanted to create that specific many-to-many relationship. But the API method would be more configurable if you wanted to do something odd with that CourseStudents (or StudentCourse) table, while the annotation method would be more limited but is easier to read at a glance if you don't need the extra functionality.
Let's say I have a project where I use Entity Framework, but I want to use my own classes instead of the EF classes.
Reasons for using my own classes:
Easy to add properties in code
Easy to derive and inherit
Less binding to the database
Now, my database has table names like User and Conference.
However, In my domain project, I also call my files User.cs and Conference.cs.
That means I suddenly have two objects with the same naming, which is usually very annoying to work with, because you have to use namespaces all the time to know the difference.
My question is how to solve this problem?
My ideas:
Prefix all database tables with 'db'. I usually do this, but in this case, I cannot change the database
Prefix or postfix all C# classes with "Poco" or something similar
I just don't like any of my ideas.
How do you usually do this?
It's difficult to tell without more background but it sounds like you are using the Entity Framework designer to generate EF classes. This is known as the "Model First" workflow. Have you considered using the Code First / Code Only workflow? When doing code first you can have POCO classes that have no knowledge of the database, EF, or data annotations. The mapping between the database and your POCOs can be done externally in the the DBContext or in EntityTypeConfiguration classes.
You should be able to achieve your goal of decoupling from EF with just one set of objects via code first.
To extend the above answer, the database table name User (or Users as many DB designers prefer) is the identifier for the persistence store for the object User that's defined in your code file User.cs. None of these identifiers share the same space, so there should be no confusion. Indeed, they are named similarly to create a loose coupling across spaces (data store, code, development environment) so you can maintain sanity and others can read your code.
I'm having some trouble using EF Code First to model a graph structure. I have a situation whereby numerous concrete objects within my application can be nodes that relate on any of a number of types of edge.
For example, two User objects may have a relationship (like, dislike, related to), but each could equally relate to another type of object ('viewed' page, 'liked' message etc.)
To model this within the application I'm using a base class of GraphNode from which all of the possible nodes will inherit, and each GraphNode has a collection of Edges. Each Edge has a SourceNode, a DestinationNode and a RelationshipType (used for weighting).
I know how I would model this as a straight Database-first development, with a table for Edge that would have a surrogate key, SourceObjectID and DestinationObjectID fields which would be the PKs from the objects being linked, SourceObjectType and DestinationObjectType fields which are the type of object being related, but the site requires EF Code First implementation.
I've got it to a point where I'm using TPT inheritance, so I've got a GraphNode table with a PK that's the GraphNodeID, but it's then using this as the PK for each of the tables for the concrete types, in place of their own PKs which is going to cause problems.
Has anyone done this, or can anyone point me in the right direction for a way to do this?
As you've found out, inheritance is not a great fit for this scenario.
Other ORMs, like NHibernate, provide out-of-the-box support for "heterogeneous associations". Since EF does not, my solution is to handle this at the "service" layer (i.e. between the controllers/viewmodels and the DbContext).
What I do is create an abstraction that lets me store and retrieve elements (in my case, Notes or Comments) associated to any entity. I do that by manually storing the entity type and id of the referenced object.
This is mostly trivial except when you want to associate the elements with a non-yet-persistent entity (I handle that using some callbacks in my DbContext)
My model turns my join tables into a many-to-many relationship in the model editor. This means that when I query a table through the many-to-many relationship to a row in the other table, I get the EntityCollection instead of IQueryable.
It is my understanding that it is more efficient to stick with IQueryable because EntityCollection loads instances of the entity classes into memory then queries those.
I'm not sure it's exactly what you're looking for, but EntityCollection<T>.CreateSourceQuery() will return a new instance of ObjectQuery, which implements IQueryable<T>.
Check out http://www.asp.net/entity-framework/tutorials/creating-a-more-complex-data-model-for-an-asp-net-mvc-application and look in the Customizing the Database Context section. There is a fluent API example of how to use join tables on many-to-many relationships. When I have a DB already defined, I like to create my own model classes and use Fluent API and Data Annotations to link them to the appropriate tables. That way I control how the application uses those tables instead of trusting the framework to build the way it thinks it needs to be built. This does two things: 1) It ensures that you are familiar with how the app uses your data, and 2) gives you more control over how data is represented in the app.
Happy coding!
I have a question about inheritance in Entity Framework 4. We are using a database-first approach and would like to restructure our model to use inheritance. Here is a white board mock up of the hierarchy we would like to use in our model.
Image 1
In case those scribbles are not very readable, it's something like this.
USER <- PROVIDER
USER <- VENDOR
PROVIDER <- EMPLOYEE
So USER is the base class for providers and vendors. And employee then inherits from provider.
I found a couple great articles describing Table-Per-Hierarchy inheritance and Table-Per-Type inheritance.
They seem simple enough but both ways require an entity to be mapped to a table or tables. What if you have an entity that is mapped entirely to stored procedures?
Image 2
Is it still possible to do inheritance in EF even if an entity is mapped to stored procedures? How would that look? What kinds of stored procedures would we need to have to accomplish this?
If it's possible we really just need pointed in the right direction.
I have searched and searched and finally arrived at the conclusion that it is not possible to do inheritance with entities that are mapped to stored procedures. So unless someone can prove otherwise, I'm marking this as the answer.
I am using a completely stored procedure mapped repository architecture in my MVC project. In that we are not using the entity framework, instead of that we use Microsoft Enterprise Library. We are using the methods from it. From my experience, The repository contains only methods for data manipulation using stored procedures. The Tables are mapped to Models. There are ViewModels which are custom Model classes for handling properties which are defined as custom in the project. There is one service layer to separate the Controllers and Repositories. So I think you can adopt the method of repository mapped entirely to stored procedures