Conceptual side cannot be mapped to object side? - entity-framework

I use the Entity Framework with Db-First approach. I used to have a table called Ranking that I mapped to an abstract base class with a few inherited concrete classes. Now I recently removed all the inheritance and choose to just use one concrete class called Ranking.
But since I changed it back I get the following runtime Exception:
Type 'DbModel.Ranking' in conceptual side cannot be mapped to type 'My.Application.Models.Ranking' on the object side. Both the types must be abstract or both must be concrete types.
In my code generation I have set Abstract to false, but I don't know how to change this on the conceptual side.
I even tried deleting the Ranking table from my table designer, and then update it again from the database. This didn't help either.
Anyone an idea?

Found it. There was a partial class defined where I forgot to remove the abstract modifier.
So the generated partial class didn't had the abstract modifier anymore, but the other partial still had.
Pretty stupid after all, but hopefully this prevents some other people wasting half an hour.

Related

JPA spec requiring no-arg constructor disables us to write completely correct hashcode/equals. How do you cope with that?

Ok, so here [1] is the great read, how do really correctly define hashcode/equals, namely with respect to object hierarchies. But here I'd like to ask about #pitfall 3 from that article, which shows bizarre behavior when hashcode/equals are defined on mutable fields and Set is used for collections. We cannot use final fields and parameterized constructor only, due to JPA spec. So what are the means to avoid these gotchas? What do you use?
Well, obviously one is to avoid using Set in JPA entities. Does not seems very nice. Another solution could be to "unsupport" setters after equals method was called, but that's ridiculous and equals surely shouldn't have side-effect.
So how do you cope with that? Aside from not-knowing/ignoring it, which probably would be default action in java world...
[1] https://www.artima.com/lejava/articles/equality.html
If entity is detached you need to override equal and hashcode1. Every entity has to have #Id. ID is immutable. Entities should implement equal and hashcode based on primary key ID.
Pitfall 3 deals with mutable object. Cannot by applied on entity with immutable ID.
Guide to Implementing equals() and hashCode() with Hibernate

Why is the parent class abstract when doing inheritance in EF?

In almost all EF methods that use inheritance, I see that the parent class is marked as abstract. Is there any reason why this is done? Or is it just so the abstract class cannot be instantiated?
No, that is not mandatory, your base class could not be abstract, but as you already said it's the most common. It's like a inheritance by generalization, which is extracting shared characteristics from two or more classes, and combining them into a generalized superclass, that's why is common see the base class as abstract.
In EF there are three different approaches to representing an inheritance hierarchy:
Table per Hierarchy (TPH): Enable polymorphism by denormalizing the
SQL schema, and utilize a type discriminator column that holds type
information.
Table per Type (TPT): Represent "is a" (inheritance) relationships as
"has a" (foreign key) relationships.
Table per Concrete class (TPC): Discard polymorphism and inheritance
relationships completely from the SQL schema.
In the last approach if the base class was concrete, then an additional table would be needed to hold instances of that class.
In summary, if the base class is abstract or not depends more on your side if that make sense or not in the model you are trying to represent.
I'd assume because the methods you override are also abstract? Can't have an abstract method on a non-abstract class.
So, for example, it never makes sense to instantiate a plain old DbContext -- you always need collection properties and such. The base DbContext provides functionality which all DbContext derivatives would need (connecting to a database, etc), but isn't useful as a stand-alone object.

EF Code First - Models , when should properties be instantiated in constructor?

I was wondering if there is a good explanation somewhere as to when a Property will need to be instantiated
in a model class constructor and when it is not necessary?
Docu on the MS EF site is good and covers a lot of related topics
Relationships and Navigation Properties - http://msdn.microsoft.com/en-us/data/jj713564
Configuring relationships with API http://msdn.microsoft.com/en-us/data/jj591620%20%22Configuring%20relationships%20with%20API
Entity Framework class library http://msdn.microsoft.com/en-us/library/hh289362%28v=vs.103%29.aspx
and im also part way through reading the Book Programming Entity Framework - Code First By Julia Lerman
I would like to better understand when a property needs to be instantiated in the Model constructor.
I see Samples in MS documentation and in the Book with and without newed up properties in the Model constructor.
There is most likely a good reason why some solutions use a constructor with newed Up objects and others not.
Seems like Virtual ICollection has the new List<> and complex type has new RefObj.
But simple virtual navigation property of type ModelObject are Ok without new.
Can I stick to a pattern without knowing the internals of each convention class. Or is there another topic I should be reading?
You never need to instantiate a property in the models constructor for EF to work, but it make it more convenient.
For example, If you had a class Order and it has children of Order Detail, and you wanted to add a new Order to your database.
Without initializing OrderDetails
var order = new Order();
order.OrderDetails.Add(new OrderDetail()); // this would error because OrderDetails is null
One option could be to call order.OrderDetails = new List();
before you use Add(), but then you would need to have that code repeated everywhere you wanted to use Add(). Instead you can put that code in the constructor, and then OrderDetails will be ready to use with all newly created Orders.

Unable to specify abstract classes in TPH hierarchy in Entity Framework 4

I have a TPH heirachy along the lines of:
A->B->C->D
A->B->C->E
A->F->G->H
A->F->G->I
I have A as Abstract, and all the other classes are concrete with a single discriminator column.
This works fine, but I want C and G to be abstract also. If I do that, and remove their discriminators from the mapping, I get error 3034 'Two entities with different keys are mapped to the same row'. I cannot see how this statement can be correct, so I assume it's a bug in some way.
Is it possible to do the above?
Lee
Seeing as they are abstract - so there are no entities in the database - have you tried just lying and pretending they do have a discriminator.
This should satisfy the mapping, but since the classes are abstract you still won't be able to create or materialize.
Alex

Table per hierarchy inheritance with POCO entities in Entity Framework 4

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.