I am facing a problem with EF 4.1. I am trying to Add a detached object to the DbContext. Problem is it is not the emd mapped object, but derived from it. Changing the mapping is not an option as some teams are using the model with the regular mapped BL-classes, but my project created a derived model for UI stuff. Even with casting I always receive a
InvalidOperationException ("Mapping and metadata information could not be found for EntityType ...").
What I want is EF to treat this as the base class and put the object into the DbSet of the BaseClass. The current EF code is:
Context.Entry(object).State = EntityState.Added
But I am open for other suggestions, even
via IObjectContextAdapter, as long as it can save the Base and the Supertype. This should be simple, right?! Mapping to a new Base-class instance is not good idea as the main objects temporary Id would not be updated after saving...
Thanks!
As I know this is not possible. You cannot use derived class from the entity instead of the entity. You must either map derived class as well or create new instance of the entity for persistence and copy all fields from your derived class instance to the entity instance.
Related
At work, there is an application was developed using Entity Framework Database First approach. Therefore, our business entity classes are derived from Entity Framework Database First's EntityObject class.
Our team was to modify the application by moving from Entity Framework Database First approach to Entity Framework Code First approach.
However, we have to modify all out business entity classes that derive by modifying them in such a way that they Stop inheriting from the EntityObject class.
The problem is that we use a lot of EntityObject class's methods and other features in a lot of classes.
We were planning to create a BasePOCO class that will replace the Entity Frameworks Database First EntityObject class.
We would have to implement some methods in the BasePOCO class that would function in the same manner as some methods in the EntityObject class.
For example, we have the following line in a code file ( entity instance in the line of code below being of type EntityObject )
entity.GetType().GetProperty(firstFilter + _referenceKey);
we can replace it with (we have to implement methods that do something similar):
basePOCOEntityObject.GetType().GetProperty(firstFilter + _referenceKey);
I'm assuming there were probably many companies who moved from Entity Framework Database First approach to the Code First approach
Therefore, Has anyone already created something like out BasePOCO (which basically has a lot of functionalities that is similar to Entity Frameworks Database First EntityObject class)?
GetType() is not an EntityObject method. It's available on all objects.
EntityObject's methods mostly are replaced by methods on the DbContext.ChangeTracker. The main difference is that you have to have a DbContext object to call these methods. This can require some code restructuring.
I have extended Entity Framework autogenerated classes with custom partial classes and added several new properties and business login into it. I need to populate those properties any time objects are either materialized from the database or created from scratch without a database contact.
Can I use or is it advised to use the New() method inside the class for that? (I know there is an event ObjectContext.ObjectMaterialized as well).
As an example, in my partial class i have a property
Public Property Employees As List(Of Employee)
and I want to instantiate that list somewhere (where?).
You could just write a default constructor for those entities where you set default property values. Notice Entity Framework doesn't create constructors for you, so they can easily be added in partial classes.
I have an application with the following layers:
Specific WebAPI Controller -> Generic WebAPI Controller Parent Class -> Generic Repository Class -> Entity Framework -> Database
The problem I'm getting is that when I try to retrieve an object with related objects, for instance, BlogPost, with Category and User, the latter two are being returned null. I have the proper relationships defined at the Model (which EF can infer from) as well as foreign key relationships in the database.
I figured this is because my generic repository does a Get only for the main class, and does not include the others.
I know I can get the others if I put in "Include", but how can I do this with generic layers? If I override my methods, that will probably mean that I won't be using the generic methods for majority of my implementation.
Is there another way to tell EF to retrieve the child objects without having to resort to Get overrides?
I wonder if anyone can help me?
I am having problems understanding why i need to issues DetectChanges on my POCO (non proxy) entities.
Of course i have this line to ensure that proxies are not returned.
context.ObjectStateManager.GetObjectStateEntry(order).State
And doing some research it appears if i need to check the "state" of an object then i need to issue detechChanges But why would i need to check the State of an object?
Basically I send along my POCO entity to a method that SAVES the data to a new ObjectContext (I create and destroy ObjectContext on each method)
Hence, i am having problems understanding why i would need to have ObjectContext track or be aware of changes?
Is it because that if its not aware if will not be saved?
Maybe i am miss informed but it appears that if i am using an existing ObjectContext (which i am not i am creating and destroying each time) that ensure ObjectContext is aware would be beneficial but otherwise not?
So in 1 method I am updating an object by creating a new datacontext, saving it to the db and destroying ObjectContext . Hence i am not using 2 methods, 1 method to send the update or new record and then another method for SAVING.
I would really appreciate any quick explaanations of why its needed?
Thanks in advance
Your question is little bit confusing. You are writting about Entity Framework but using DataContext which is related to LinqToSql.
The behavior differs in the way you are using ObjectContext. When you load POCO entity from database ObjectContext holds its instance in internal Identity Map. By default POCO doesn't use any kind of change tracking. When you save that POCO entity to the same instance of ObjectContext it internally calls DetectChanges to compare current entity state with stored state. This comparision defines which columns have to be updated. Internal call to DetectChanges is default behavior which can be turned off so you will have to call this method manually.
In your scenario you not using the same instance of ObjectContext. In that case you first have to Attach POCO entity to the ObjectContext. MSDN strictly says that when attaching entity it is marked as Unchanged. For that reason you have to say ObjectContext that entity has changed. You can do that for whole entity or you can define exactly which properties have changed but you have to do it manually = you have to store that information somewhere (Self tracking entities can help you with that but they have ohter disadvantages).
Our organization is looking to standardize on Entity Framework once v4 comes out. As a result, I am looking at what it would take to migrate our application that uses NHibernate for persistence to EF4 using POCO support. In a couple of places we use single table inheritance (also known as Table Per Hierarchy). I have been unable to get it to work using the following.
Payment (base class [should be abstract but having trouble there as well])
CreditCardPayment (concrete implementation)
ACHPayment (concrete implementation)
CheckPayment (concrete implementation)
Right now, I am mapping them with only the base class properties. All of these classes are in the same namespace. They have a discrimimator that is called PaymentTypeId in the database, so the Payment mapping has a condition of "When PaymentTypeId = 0". Each of the subclasses have the same condition with different values (i.e. CreditCardPayment = 1, etc.).
When I try to load each a list of all payments using DataContext.Payments.ToList() (DataContext inherits from ObjectContext) I am getting the following exception:
"Object mapping could not be found for Type with identity 'DataLayer.DataModel.CreditCardPayment'."
I can't figure out what this means, as the POCO CreditCardPayment class lives in the same namespace as the POCO Payment class does (in fact in the same file).
What am I missing?
This is complaining not about database mapping, but model to CLR mapping.
The EF can't for some reason find your CreditCardPayment class.
Now one possible reason is that you haven't loaded the metadata for it yet.
For example if you have this:
Assembly 1:
- Payment
Assembly 2 references Assembly 1:
- CreditCardPayment extends Payment
Then when you query the EF doesn't know where CreditCardPayment lives.
The way to get around this is with LoadAssembly i.e:
using (DataContext ctx = new DataContext())
{
ctx.MetadataWorkspace.LoadFromAssembly(typeof(CreditCardPayment).Assembly);
// now do your query.
}
You need to tell to LoadFromAssembly every assembly that isn't directly reference by your DataContext class.
Note: typeof(Payment).Assembly is directly referenced because of the IQueryable<Payment> Payments property.
Hope this helps
Alex
Microsoft.
What I didn't represent before (I didn't think it relevant, but it was). Was that CreditCardPayment inherited from an intermediary class named "CreditPayment" and ACHPayment inherited from CashPayment. CreditCardPayment and CashPayment live in the same namespace and file, but were not represented in the EF mapping. Once I added those within the mapping file, everything worked ok.
So, even thought EF does not ever map to one of those types directly, it seems to need to know about them, because it changes the basetype of the CreditCardPayment classes et al. Thank you for your help on this.