Many-to-Many Relationships in EF4 with "Shared" columns - entity-framework

Disclaimer: Strictly speaking, what I have here is not a many-to-many relationship, but given that it's using an associative table, I figured it would be better to be slightly less accurate in order to give a better idea of what I'm doing.
I have the equivalent of the following three tables in my database:
Customer
---------
CustomerID PK
...
CustomerAddress
---------
CustomerID PK, FK -> Customer
AddressNo PK
... address columns ...
CustomerPrimaryAddress
--------------
CustomerID PK, FK -> Customer
AddressNo FK -> CustomerAddress (with CustomerID, so CustomerID
participates in both relationships)
If it's not obvious, the intent here is to allow for multiple addresses per customer, while designating at most one address per customer as "primary". I'm using an associative table to avoid placing a nullable PrimaryAddressNumber column on Customer, then creating a foreign key from Customer to CustomerAddress.
This is all well and good, but EF then places the CustomerPrimaryAddress entity in my model. Since its one and only purpose is to serve as an associative table, I have no need to represent this table in code. I removed the CustomerPrimaryAddress table from the conceptual model, then created an association between Customer and CustomerAddress like so:
Table Customer CustomerAddress
Multiplicity 1 0..1
I then mapped the association to use the CustomerPrimaryAddress table from the storage model, and all of the columns mapped just fine, or so I thought.
My issue is that now EF is complaining that CustomerID in CustomerPrimaryAddress is being mapped to two locations in my association, as it's mapped to both Customer and CustomerAddress.
Is there any way around this? I would prefer not to add a nullable column to Customer to represent the primary address number, as not only is this not a pleasant option from a DBA perspective, EF will also complain about having a cyclical relationship and I'll have to break inserts up in the code.

Thinking out loud here:
Customer
---------
CustomerID PK
...
CustomerAddress
---------
AddressNo PK
CustomerID FK -> Customer, non-nullable
... address columns ...
CustomerPrimaryAddress
--------------
CustomerID PK, FK -> Customer
AddressNo FK -> CustomerAddress
This seems like it should get the cardinalities right, but I may have missed something.

Related

Postgres 2 different FKs in both directions

I've run into a situation where we have 2 tables that have 2 different foreign key relationships, one is 1-many, the other is 1-1, but they are in opposite directions. I'm wondering if postgres has a way to validate that the combination of the FKs must match, probably easier to show in an example.
table product {
id: PK
name ...etc
preferred_vendor_product: FK to vendor_product id
}
table vendor_product {
id: PK
product_id: FK to product (a product could have many vendor products)
price...etc
}
Is there a way to enforce that when I add a preferred vendor product to product, that not only the vendor_product must exist, but it's value in product_id must match the product in question.
Just have a third table preferred_vendor_product that just has a fkey pointing to vendor_product. That table presumably should have a primary key of (vendor_id, product_id).

Entity Framework - How to Insert to table with foreign keys without retrieving foreign table rows first

I'm having a hard time finding the exact answer to this question, so my apologies if this is redundant.
So I have 3 tables defined such that:
Person :PersonId, FirstName, LastName
Company: CompanyId, CompanyName
Order: OrderId, PersonId, CompanyId
On the Order table, there is a foreign key defined on the PersonId and CompanyId columns, thus, my Order entity class generated by EF has a navigation properties of type Person (not PersonId) and Company.
So, to insert into the Order table, I first need to query the person and company tables to get the person and company entities. Then I can construct the Order object using the Person and Company entities and save it to the db.
In my scenario, I am being passed a PersonId and CompanyId.
In classic SQL I would just do INSERT INTO Order Set (CompanyId, PersonId) - 1 database call. But with EF, I have to do 3 db calls. This seems like overkill.
Is there any way around this?
PS - I'm using EF 6. I know I could generate an expression and make it single call..but that would still yield two subselects.
You can just include foreign key properties in addition to the navigation properties and then set them using the ids you have. If you do this will not have to go to the database to get related entities for just a sake of setting the relationship.

Map tables relationship from legacy database w/ entity framework with only primary keys

data (table name)
dataid PK,
value1,
value2,
value3
data_address (table name)
dataaddressid PK,
dataid - id to errenddataid,
addressid1 - id to en addressid,
addressid2 - id to en addressid,
type
address (table namne)
addressid PK - id to addressid1 or addressid2,
address1,
address2,
name,
zipcode,
city
I have a really hard time trying to map this relations using Entity Framework 5, if some one have an idea or good links I would much appreciate that!
If you are certain that the database's integrity is sound you could just map the tables and create the associations manually in the EF model.
In a database-first mode I fiddled a bit with a simple data model: Parent + Child without FK. The tables were of course imported without association between them. Then I did "Add Association..." on the Parent, like so:
Note: no foreign key property yet. I added it manually in the properties of the association:
And I could run a linq query on Parent.Children.
I think this is the easiest way for you. The edmx design surface gives you some guidance to see which associations you created. You can always add a code generation item to generate a DbContext which is easiser to work with than the default ObjectContext.

Entity Framework table per type inheritance with PK->FK, not PK->PK

I have to create an entity framework model for a badly designed database. The database uses table per type inheritance but it does so with using a PK->FK relationship, not a PK->PK relationship. E.g.
Person
PersonID (PK)
Name
Employee
EmployeeID (PK)
PersonID (FK)
DateStarted
HourlyEmployee
HourlyEmployeeID (PK)
EmployeeID (FK)
HourlyRate
Obviously this is just badly designed, but I can't change it. Table per type inheritance in the entity framework essentially wants EmployeeID not to exist and the PK for Employee to be PersonID. Is it possible to create a model for this database, or do I choose another tool? any recommendations?
You will not map this as TPT inheritance because your database is configured in the way that doesn't allow you cheating EF.
If Employee.EmployeeID is auto-generated in the database and Employee.PersonID is unique (uniqueness must be enforced in the database) you should be able (not tested) to cheat EF by simply mapping:
public Employee : Person {
public DateTime DateStarted { get; set; }
}
This class will tell EF that Employee inherits key from Person (PersonID) and you will hide the real key from EF - this should work if the real key is auto-generated.
The problem is your next level of inheritance which breaks this pattern. To make this work your HourlyEmployee will have to reference PersonID - not EmployeeID. EF now doesn't know about EmployeeID existence so it even cannot map relation with HourlyEmployee.
TPT inheritance in code first has one additional limitation - PK column must have the same name in all tables.
You can create a model from the database if it exists but it might not be what you expect. EF sometimes doesn't work that great with weird database structures.

What 'possible data inconsistency' is entity framework worried about in a 'foreign key participating in multiple relationships' situation?

Suppose the following database schema:
Table A: AId (PK)
Table B: BId (PK)
Table C: CId (PK)
Table AB: AId, BId (composite PK, FKs to A and B), Data
Table BC: BId, CId (composite PK, FKs to B and C), Data
Table ABC: AId, BId, CId, Data
In the database, ABC has two FKs: one to AB on AId and BId, and one to BC on BId and CId.
Use the EF Designer and attempt to create a Model from this database.
If you have Include foreign key columns in the model checked, it works; but having FK Columns in the model isn't very nice.
If you have Include foreign key columns in the model unchecked, only one of the FKs from ABC will be successfully mapped. To see what went wrong, you have to view the .edmx xml (thanks Craig!) and you see this error:
warning 6037: Foreign key constraint 'FK_ABC_BC' has been omitted from the storage model. Column 'BId' of table 'Model.Store.ABC' is a foreign key participating in multiple relationships. A one-to-one Entity Model will not validate since data inconsistency is possible.
I've read the only other mention of this problem I can find on SO, and I don't think this is the same problem. I can't see anything wrong at a database design level. I'm going to work round this for the time being by imposing surrogate keys on AB and BC, but what I'd really like to know is:
What possible data inconsistency is EF worried about happening here, if it created a model to match the database?
And is there anything I can do to persuade it that everything's going to be OK?
My opinion is that EF is too clever in this scenario and it prevents you from using entity where you can assign only one relation and make the entity non-savable because relation to second entity will not exists.
There is also possibility that EF has some internal problem with tracking state of independent associations if more than one association is based on the same foreign key column but that is just another guess. Generally database features used to map EF features cannot be shared among multiple constructions. The only exceptions I can think about now are primary keys and in their own way discriminator columns.
I would like to mention that I don't like this type of relations in database at all.