Entity Framework 4.0, PoCo & Navigation Properties for Lookup Tables - entity-framework-4

I have the following Models
DeltaDirectionType,
int Id
string Name
Delta,
int Id
string Name
DeltaDirectionType DeltaDirectionType
Double Value
Trade
int Id
DateTime BusinessDate
IList<Delta> deltas
So DeltaDirectionType is a lookup table, Trade holds a collection of Deltas
In the database it is implemented as follows
DeltaDirectionTypes
Id int
Name varchar(max)
Deltas
Id int
Name varchar(max)
DeltaDirectionType_Id int
Trade_Id int
Value float
Trades
Id int
BusinessDate DateTime
Delta_Id int
When I generate the model from code for the Edmx file, and (un check the foreign keys) as my model does not have properties for these. I am having problem with the navigation properties. Something like this in nHibernate would be a simple one to many mapping for the DeltaDirectionType and Delta and a many to many for Delta and Trades however, how do I firstly get it to recognise that DeltaDirectionType is a lookup and secondly get the Icollection to work for me.
I am struggling with this, Entity Framework does not make it easy for you. I have tried the usual, delete the navigation property that EF puts in for you on one side, but then you get some mapping fragments errors, properties not mapped etc.
Please help or point in the right direction.
Lookup tables are real life problems, not sure why it is so hard withing EF to implement.
Any help much appreciated
Thanks

You must either create foreign keys or navigation properties in the model to navigate the relationship.
Navigation properties can be defined as one-way, ie from the deltas table to the look-up table. A one-way navigation like this would add the appropriate property to the delta's object but not to the looup table

What you actually mean by lookup? Do you except that Delta entity will have DeltaDirectionType_Name directly mapped?
In EF you will get navigation property to DeltaDirectionType and you can access the name through this navigation property. If you don't like it you can add new property to partial class of your generated POCO and provide the Name directly in Delta entity like:
public string DeltaDirectionTypeName
{
get
{
return DeltaDirectionType != null? DeltaDirectionType.Name : String.Empty;
}
}
The only problem is that you can't use this property in Linq-To-Entities queries. In queries you always have to use navigation properties.

Related

F# recursive types to SQL tables

I'm modeling an application in F# and I encountered a difficulty when trying to construct the database tables for the following recursive type :
type Base =
| Concrete1 of Concrete1
| Concrete2 of Concrete2
and Concrete1 = {
Id : string
Name : string }
and Concrete2 = {
Id : string
Name : string
BaseReference : Base }
The solution I've got for the moment (I've found inspiration here http://www.sqlteam.com/article/implementing-table-inheritance-in-sql-server) is :
I have two concerns with this solution :
There will be rows on the Base table even though that doesn't make sense in my model. But I can live with that.
It seems that queries to find all the information about BaseReference of Concrete2 will be complex since I will have to take into account the recursivity of the type and the different concrete tables. Moreover, adding a new concrete type to the model must modify these queries. Unless of course there is an equivalent to the match F# keyword in SQL.
Am I worrying too much about these concerns? or maybe, is there a better way to model this recursive F# type in SQL tables?
Part 1: Encoding Algrebraic Data Types in Relational Tables
I've struggled with this very thing many times. I finally discovered the key to modeling algebraic data types in relational tables: Check constraints.
With a check constraint, you can use a common table for all members of your polymorphic type yet still enforce the invariant of each member.
Consider the following SQL schema:
CREATE TABLE ConcreteType (
Id TINYINT NOT NULL PRIMARY KEY,
Type VARCHAR(10) NOT NULL
)
INSERT ConcreteType
VALUES
(1,'Concrete1'),
(2,'Concrete2')
CREATE TABLE Base (
Id INT NOT NULL PRIMARY KEY,
Name VARCHAR(100) NOT NULL,
ConcreteTypeId TINYINT NOT NULL,
BaseReferenceId INT NULL)
GO
ALTER TABLE Base
ADD CONSTRAINT FK_Base_ConcreteType
FOREIGN KEY(ConcreteTypeId)
REFERENCES ConcreteType(Id)
ALTER TABLE Base
ADD CONSTRAINT FK_Base_BaseReference
FOREIGN KEY(BaseReferenceId)
REFERENCES Base(Id)
Simple, right?
We've addressed concern #1 of having meaningless data in the table representing the abstract base class by eliminating that table. We've also combined the tables that were used to model each concrete type independently, opting instead to store all Base instances--regardless of their concrete type--in the same table.
As-is, this schema does not constrain the polymorphism of your Base type. As-is, it is possible to insert rows of ConcreteType1 with a non-null BaseReferenceId or rows of ConcereteType2 with a null BaseReferenceId.
There is nothing keeping you from inserting invalid data, so you'd need to be very diligent about your inserts and edits.
This is where the check constraint really shines.
ALTER TABLE Base
ADD CONSTRAINT Base_Enforce_SumType_Properties
CHECK
(
(ConcreteTypeId = 1 AND BaseReferenceId IS NULL)
OR
(ConcreteTypeId = 2 AND BaseReferenceId IS NOT NULL)
)
The check constraint Base_Enforce_SumType_Properties defines the invariants for each concrete type, protecting your data on insert and update. Go ahead and run all the DDL to create the ConcreteType and Base tables in your own database. Then try to insert rows into Base that break the rules described in the check constraint. You can't! Finally, your data model holds together.
To address concern #2: Now that all members of your type are in a single table (with invariants enforced), your queries will be simpler. You don't even need "equivalent to the match F# keyword in SQL". Adding a new concrete type is as simple as inserting a new row into the ConcreteType table, adding any new properties as columns in the Base table, and modifying the constraint to reflect any new invariants.
Part 2: Encoding hierarchical (read: recursive) relationships in SQL Server
Part of concern #2 I think about the complexity of querying across the 'parent-child' relationship that exists between ConcreteType2 and Base. There are many ways to approach this kind of query and to pick one, we'd need a particular use case in mind.
Example use case: We wish to query every single Base instance and assemble an object graph incorporating every row. This is easy; we don't even need a join. We just need a mutable Dictionary<int,Base> with Id used as the key.
It would be a lot to go into here but its something to consider: There is a MSSQL datatype named HierarchyID (docs) that implements the 'materialized path' pattern, allowing easier modeling of hierarchies like yours. You could try using HierarchyID instead of INT on your Base.ID/Base.BaseReferenceID columns.
I hope this helps.

Use Enum in Entity Framework Database first?

I have a prolem when use Enum for Database first.
I have two table:
Table1:
Id int
Label nvarchar(50)
StatusId int
Table2:
StatusId
Label
I created a Constrains key for two table, and in Asp Mvc. i load both into a Model.edmx. so I want to convert StatusId in Table1 to an enum for easy operation, but i cannot do it.
What is wrong? How can i do it? I don't want to remove Table2 from Model.
Thank in advance!
enum is implemented in the CLR as an int32, but it is not an int32. It is a separate type, so you cannot use in the Entity Framework. But could use it to reference an int32 in the other entity.
I would rather suggest to go Code First Approach for implementing your ideas.
Use this link for details and samples about Code First Approach

EF4 DB-first: TPH approach?

I know this should not be trivial, but so far couldn't find the resolution...
Working with an EF4 DB-First model, using LINQ-to-Entities with POCOs which will be consumed by an MVC3 app.
I have three entities Customer, CustomerAdress and a lookup CustomerAddressType.
Customer CustomerAddress CustomerAddressType
---------- ---------------- -------------------
CustomerId (PK) CustomerAddressId (PK) CustomerAddressTypeId (PK)
LastName CustomerId (FK) Description (Values: Mailing, Billing)
FirstName CustomerAddressTypeId (FK)
MiddleInitial Address
.... City
State
Zip
StartDate
EndDate
As you can see CustomerAddress has a FK CustomerAddressTypeId, which identifies what type of address this is, i.e. Mailing or Billing.
I would like to:
Have is ability to do something like this: Customer.CustomerAddress.OfType<MailingAddress> to get the collection of mailing addresses for the customer.
Have a CurrentMailingAddress and CurrentBillingAddress properties, that would return the single instance CustomerAddress.OfType<> with the highest StartDate and EndDate in the future.
Would be also nice to take Address thru Zip properties and refactor those propertiess into a Complex Type Address.
I tried creating 2 inherited entities off of CustomerAddress (assuming it is TPH [table-per-hierarchy] strategy):
MailingAddress and BillingAddress, CustomerAddressTypeId being the discriminator. I did this in the model designer, and as soon as I tried adding a second inherited entity, it told me that the properties with those names already existed, and wouldn't let me rename them to match the properties of the first entity.
Any ideas how to accomplish this? Please dumb it down for me :)
Thanks!!!
It is not such trivial. TPH will be possible but you must place all properties to the base CustomerAddress and derive two sub entities which will not hold any property because all properties are shared (= must be in the parent). You will use CustomerAddressTypeId as discriminator and because of that you will not be able to map this field as property in the entity. I'm also not sure if you can have the field both in discriminator and association mapping (that is actually nice homework for me). If not you will not be able to map association between CustomerAddress and CustomerAddressType.
Both CurrentMailingAddress and CurrentBillingAddress are computed properties and they are not part of mapping. It is up to you to implement their logic in your partial part of Customer entity.
I don't understand the last point with Zip and complex type.

One to One error in Entity Framework 4

I have already read Entity Framework One-To-One Mapping Issues and this is not duplicate as the business rule specs are different here.
There are two tables, Invoices and Orders.
Invoices
-> InvoiceID (Primary, Auto Number)
Orders
-> OrderID (Primary, Auto Number)
-> InvoiceID (FK InvoiceID of Invoices Table)
Now the problem is, EF requires One to Many relationship for this association if names of properties are not same. If names of properties are same then it serves purpose of derived class, but here Order is not derived class or Invoice.
InvoiceID(s) are generated for every shopping cart, but OrderID(s) are only generated for paid invoices, so Every Order has InvoiceID but every Order does not have corresponding Invoice.
If I create a seperate table for this, then I have to write too much code to do it. Is there any way I can remove this restriction and let EF still process my model.
However, currently if I change the model as follow, it works
Invoices
-> InvoiceID (Primary, Auto Number)
Orders
-> OrderID (Auto Number)
-> InvoiceID (Primary, FK InvoiceID of Invoices Table)
But is this good practice? Because by definition InvoiceID of Orders table will certainly be unique, but we will be referring everywhere OrderID for comparison and lot of other references. I know I can index the property, but I dont feel this design is perfect.
What seems to be the obvious solution here is to change the 1:* association between Invoice
and Order in the EDM into a 1:1 association. However, as you experienced, the mapping will not
validate when you have a Foreign Key Association between the two entities as in your model.
The only way to map a unique foreign key association is by using an Independent Association. This is the same type of association that we had in EF3.5, where foreign keys were not supported.
To turn the foreign key association into an independent association would mean removing the InvoiceID foreign key from the Order entity and recreating the association through mappings.
To make the change to the association, you’ll need to do the following:
Delete the InvoiceID foreign key property from Order entity.
Select the Asscoation between Invoice and Order.
In the Properties window for the association, open the Referential Constraints by
clicking the ellipses next to that property.
Delete the constraint by clicking the Delete button.
Right-click the association in the Designer and select Table Mapping from the context menu.
In the Mapping Details window, click the element to expose the drop-down.
From the drop-down, select Order. The mappings should populate automatically.
Return to the Properties window for the association.
For the property called “End2 Multiplicity,” which currently has the value * Collection of Orders, change that property to 1 (One of Order) using its drop-down list.
Validate the model by right-clicking the design surface and choosing Validate. You will see that the error message related to this mapping is gone.
When encountering this problem in your application, you’ll have to decide which is more important to your model and your application logic: the foreign key scalar (e.g., Order.InvoiceID) or being able to define a 1:1 association between one entity (Invoice) and another (Order) when they are joined through a foreign key (InvoiceID).
The good news is that the new EF4.0 Lazy Loading will be still working with Independent Associations, just the Foreign key is not exposed. To get that you would have to go over to the navigation property (Invoice) and read its InvoiceID like the code below:
Order order = context.Orders.First();
int invoiceID = order.Invoice.InvoiceID;
Or you can use the code below to read it right on the Order entity withought having to Lazy Load or Eager Load the Invoice property:
int invoiceID = order.InvoiceReference.EntityKey.EntityKeyValues[0].Value;

Using a navigation property as discriminator in a TPH inheritance scenario in Entity Framework 4

I am trying to create a TPH inheritance hierarchy using foreign keys / navigation properties as discriminators and I am having some trouble getting it right.
I have the following entities:
Person:
Id (int)
Name (nvarchar)
PlaneId (int)
CarId (int)
Car:
Id (int)
Name (nvarchar)
Plane:
Id (int)
Name (nvarchar)
with PlaneId and CarId beign FKs. I have corresponding tables in a database and I can create a conceptual model using the VS2010 EF wizard. The Person entity then has two navigation properties, Car and Plane.
Now I want to derive two types from Person:
Pilot (condition: PlaneId is not null)
Driver (condition: CarId is not null)
So, I add the entity Pilot, tell it to map to Person and add the condition PlaneId is not null. At this point Visual Studio (or edmgen I guess) complains that the property Person.PlaneId with 'IsNull=false' condition must be mapped.
What is my next step? I have tried various approaches, but can't seem to get it to work. Any insight would be greatly appreciated.
You can't do that. Discriminator columns must be non-nullable.

Resources