views:

1070

answers:

4

Hi all, I have the following schema in the database:

  • BillingReferences (ReferencingType tinyint, ReferencingId tinyint, ReferencedType tinyint, ReferencedId tinyint, IsActive bit) - where all fields (except IsActive) are part of a Unique Index.
  • BillingType (BillingTypeId tinyint, Name varchar(50))

ReferencingType and ReferencedType is a foreign key of BillingTypes. BillingTypes contains the following rows:

BillingTypeId | Name

1 | Labels

2 | Countries

3 | PaymentProviders

4 | PaymentOptions

5 | Banks

ReferecingId and ReferencedId represent the Id of one of the following entities (depends on the Referenced/Referencing Type):

  • Banks (BankId tinyint, Name varchar(50))
  • Countries (CountryId tinyint, Name varchar(50))
  • Labels (LabelId tinyint, Name varchar(50))
  • PaymentProviders (PaymentProviderId tinyint, Name varchar(50))
  • PaymentOptions (PaymentOptionId tinyint, Name varchar(50))

In the future each entity will have some more different columns added but for now this is the schema for simplicity.

There's a connection of (1-) between every entity (except countries) to countries. Labels have a connection of (1-) to Banks, PaymentProviders and PaymentOptions. And PaymentProviders have a connection of (1-*) to PaymentProviders

So for example if I want to connect a bank with BankId 201 to a country with CountryId 3003 I will have a record in BillingReferences that will look like that: ReferencingType = 5 ReferencingId = 201 ReferencedType = 2 ReferencedId = 3003 IsActive = 1

We didn't make a connection/reference table for each type of connection because of extendability consideration - If we want to add another entity all we have to do is add its table and add records for it in BillingReferences and BillingType.

The problem is that I can't configure a conditional foreign key between BillingReferences and each of the entities and I can't seem to configure/map it with EntityFramework either...

I was unable to find any tutorial or example that uses this type of implementation. Am I bound to create a reference table for each connection, or is there a way to configure this with EntityFramework?

Thanks for the help :)

+1  A: 

AFAIK, there's isn't a way to do this.

I'd go with creating a seperate table for each type, unless you really have a good reason not to. The consideration you mention isn't a good one, IMHO.

Having more tables DOES allow you to put foreign key constraints on your keys, and it translates nicely into the EF. It also helps performance: your big ass reference table with one million rows will take more time to query than more smaller tables (unless you ALWAYS want all references for a type).

Inferis
"unless you ALWAYS want all references for a type" - more or less...I always need to show, let's say all countries associated to a specific Bank, Or all Banks associated to a specific Label.The user has to be able to associate/deassociate any entity he wants to with the selected entity.
Captain
+1  A: 

Not only is there no way to do this in the Entity Framework, there is no way to do it in SQL, either. You can't have a foreign key which references one of five different tables.

What I think you should do instead is to have a parent, abstract reference type, and make the concrete types subtypes of this parent type. Now you have only one foreign key, to one table. You can choose table per type or table per hierarchy mapping. Given that you don't have any special columns at all in any of the types you mentioned, I would think that table per hierarchy mapping would be a better pick for you.

Craig Stuntz
You can say that every entity has its own special columnsI just described a simplified version...So I don't see how Table Per Hierarchy Mapping will do for me...
Captain
Do table per type if it's better for the parts you don't show in your question. The point is that using a supertype allows you to use a real foreign key in the DB, with the result that the EF will give you the mapping you want.
Craig Stuntz
A: 

Well, I guess I'm gonna user Inferis's suggestion and create a seperate table for each type.

Thank you guys for your answers - they helped A LOT :)

Captain
+1  A: 

The only way you could accomplish what you wanted is to build a Trigger to handle the processing on the server side. You can't map FK's like that to multiple tables. But a trigger can handle that logic. Of course that would be totally outside EF...

I would also recommend you build a separate table for each type. Simpler to maintain in the long run I think.

Jason Short

related questions