views:

227

answers:

2

I currently have a complex entity relationship setup based on my data structure in sql server 2008.

What I'm trying to do I would think would be ridiculously simple but I'm pulling my hair out and have spent days trying to figure it out.

I have an Address and AddressType table which are joined on addressTypeID. There are 2 AddressTypes, "Billing" and "Shipping". I'd like to be able to create a custom entity for both Billing and Shipping. I would have thought I could just inherit from the Address entity and add a condition to that to retrieve the correct type but its not as simple as that.

I do not want to remove the navigation properties or fields from these existing entities so that we can dive into those pre-existing entities if need be.

The goal is to create custom entities that contain fields from other entities based on certian criteria... almost like what a view does for SQL server. Literally all of the examples I found on the internet are not clear on how to do this.

What I have right now is Table per Concrete type (I believe). Everytime I try to do this vs yells at me telling me that things arent mapped etc... and I map them then get a new error message. Are there any good tuturials out there that are clear? I'd rather not dive into the ssdl, etc since those would get overwritten when I rebuild my model.

lazy loading is disabled... thats how I want it.

Why can't I just create a new entity, copy and paste the fields and set the table mapping? I created a new entity called BillingAddress, copied the fields from Address and set the table mapping.... then I get the error:

Error 297 Error 3033: Problem in mapping fragments starting at line 4525:EntitySets 'BillingAddresses' and 'Addresses' are both mapped to table 'Address'. Their primary keys may collide.

I also tried inheriting from the Address table.... error: must specify mapping fror all types in Set Addresses

A: 

Actually, it sounds more like Table-per-hierarchy, or possibly Horizontal partitioning in the conceptual model. See this MSDN page for the (rather scant) documentation on supported architectures.

If that link doesn't help sufficiently, post your exact table definitions and your desired Entity design (classes and properties), and we'll figure it out.

Stephen Cleary
Please see http://stackoverflow.com/questions/3137275/entity-framework-entity-mapping-problem
Chris Klepeis
This is a bit embarassing, but for all the EF4 work I've done, I've never touched (or learned) the XML backend. So your followup post is a bit Greek to me...
Stephen Cleary
+2  A: 

If I understand your schema correctly, you have an Address table with a discriminator column, addressTypeID, which defines which kind of Address that particular record represents. The single Address table contains both types of records...Billing and Shipping addresses. If this is the case, then you actually have a Table-Per-Hierarchy, or TPH, structure, since there is one table per class hierarchy.

You mentioned that you thought you had a Table-Per-Concrete-type, or TPC, structure. If that were the case, then your database would require both ShippingAddress and BillingAddress tables, since in TPC, there is one table per concrete type.

You would need to have a code structure similar to the following:

public abstract class Address
{
    // Common address properties
}

public class ShippingAddress: Address
{
    // Additional shipping-address specific properties
}

public class BillingAddress: Address
{
    // Additional billing-address specific properties
}

You would then need to map your class hierarchy of ShippingAddress and BillingAddress types as a TPH mapping on your single Address table, discriminated on the addressTypeID column. The AddressType column would not even play a role in the mapping, unless you wished to map by some AddressType name or surrogate key. In that case, a view that presents a merged view of the appropriate Address and AddressType tables would be your base TPH schema source, with the discriminator column being the surrogate key column included from the AddressType table.

jrista
jrista another question. If we continue in this example and wanted to have a User class which contains both a BillingAddress and a ShippingAddress, how would we model this in Entity Framework. I don't want a collection of Address classes, I want 2 distinct Associations to the same table. How can we accomplish this?
KenB
@Ken: It should be as easy as simply having two properties of the appropriate types. The ORM framework should be intelligent enough to detect which type is being used and, via your model/mapping configuration, generate the appropriate query.
jrista