One to One error in Entity Framework 4 - 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;

Related

changing the database scheme to avoid having multiple database

We have a web portal in our company that is written in asp.net MVC . right now each department have their own database but we want to avoid having multiple database because the database scheme is the same only it has diffrent data inside for each department.like each department has their own projects etc. how the database model should be changed in such a way to avoid having multiple database ?
also we want to share some elments like projects between diffrents department. how it could be done ?
The single database that you have in mind would have to have its table re-designed such that you would be able to tell, for each record in each table, what department the record relates to. Essentially you would need to add a "DeptId" column to each root-level table. By root level table I mean only the parents of foreign key relationships. Eg, if you have an OrderHeader and OrderLines, only the OrderHeader table would need to have this DeptId column. The lines relate to the header, so you won't need to add this column to the lines table as well. Alternatively, if you have a Customer table, such that each customer belongs to only one department, then you would add the DeptId column to this customer table and then you won't need it on the OrderHeader table (since order header should be referencing Customer table)
Those tables/elements that you want to share between databases just would not have the DeptId column added to them.

Insert using NHibernate for n:n relationship

I have Orders, Items and OrderItems entities with n:n relationship between Orders and Items table. I am using Fluent Hibernate for mapping, in "Order" entity there is "List" property which has "protective set". I am facing below problem, while inserting.
new Order.Items.Add(alreadyexistingitem);
Since its already existing item, in the orderitems table, a record needs to be inserted into orderitems table with new orderid and existing item id. But only new order details are inserted in order table not in associative table.
"Inverse" attribute is set for "items" bag in orders entity. So, I need to attach the newly added order while adding item like below but how can i do it as it is the list object with protective set.
Orders.Items.Add(alreadyexistingitem, *order = "neworder"*);
Below is the mapping:
model.Override<Order>(m =>
{
m.HasManyToMany(c => c.Items)
.Table(Constants.TABLE_PREFIX + "OrderItem")
.Inverse()
.Cascade.AllDeleteOrphan();
});
model.Override<Item>(m => m.HasManyToMany(c => c.Orders)
.Table(Constants.TABLE_PREFIX + "OrderItem")
.Cascade.None());
As a preliminary answer, NHibernate is smart enough to know when the same object reference is being used in two places. All you should need is a "HasManyToMany" relationship in the mapping between Order and Item.
Inverse should probably not be used on the orders side. Inverse tells NHibernate that the opposite side of the relationship has the power to define and break the relationship. Orders have items; items don't get to "choose" what order they belong to.

Using a FK as the descriminator in an inheritance mapping

Consider the following schema: Employee, and EmployeeType. Employee has a fk to EmployeeType (EmployeeType might have fields like EmployeeTypeId, Description, etc...).
Now I would like to use EF's inheritance feature to create objects HourlyEmployee, and SaleriedEmployee based on the Employees fk field.
This does not seem possible. Every avenue I have tried has failed. Since Employee's FK is the descriminator for the mapping to the derived entities HourlyEmployee and SaleriedEmployee and the FK to the table EmployeeType.
Is there anything I can do short of adding a seprate field in Employee that is an duplicate of the fk field?

EF4: Creating a 0..1 to Many Association

I am trying to add an association that I didn't have originally. I realized that two tables were technically related, and that some navigation properties might simplify what I would have otherwise had to do manually. The tables and their keys look like this:
Import
Primary Key:
Number : Int32
Date : DateTime
Hour
Primary Key:
DepartmentID : Int32
UserNumber : Int32
Date : DateTime
The association is named ImportHour. Import.Number maps to Hour.UserNumber, and Import.Date maps to Hour.Date. I am trying to add an association that is 0..1 on Import, and * on Hour with navigation properties and no additional foreign keys. When I do this, the designer tells me that the association is not mapped. If I then generate the DDL, it creates new fields Hours.Import_Date and Hours.Import_Number (Hours is the actual database table name for the Hour entity). If I manually map the fields, I end up with the following error:
Error 3021: Problem in mapping fragments starting at line 332:
Each of the following columns in table Hours is mapped to multiple conceptual side properties:
Hours.Date is mapped to <ImportHour.Hour.Date, ImportHour.Import.Date>
Hours.UserNumber is mapped to <ImportHour.Hour.UserNumber, ImportHour.Import.Number>*
I am not really sure what is happening, and I don't think I understand the 'mapping' process well enough to figure this out. It almost seems as if it wants a quintuple key, instead of realizing that the one key maps to the other. I look at my other one-to-many associations, and they do not even have table mappings; I think they have referential constraints instead, but you obviously can't have a referential constraint with a 0..1 to many association.
There are two ways to define relation but in your case you must use the Foreign key association. It means that once you draw association in entity model you must select it and define referential constraints.
You cannot have 0..1 on Import because in such case UserNumber and Date in Hour must be nullable. That is what that relation mean. If no principal entity exists (Import) FK properties in dependent entity (Hour) will be null.
Btw. using DateTime in primary key is not recommended.
As far as I can tell from other databases I have since used, the issue here seems to be that the EF model requires a foreign key to already exist in the database. While I cannot seem to get EF to generate one, it will accept one if it already exists. (Contrary to what I said in the question, you can have a referential constraint on a 0..1 to many (nullable) foreign key).
#Sahuagin this may be long after your question but did you try after adding the association, deleting the scalar property in the designer -- example after creating the ImportHour association, delete the hour.usernumber and hour.date from your hour entity.
this way the independent association established this way is the only relationship between yuor entities - thats the meaning of independent association

How to layout tables and relationships for MVC project

So I am working on an MVC project to put to work the studying I have been doing. I am wrestling with the concept of Database Table relationships and foreign keys. I am working on a simple ecommerce site (displays products, shopping cart, user accounts..etc).
I have the following tables to start out with:
1) Products
2) Categories
I setup the Products and Categories tables to have a ProductId and CategoryId respectively. In my MySQL db, I created a FK on the Products Table to relate to the CategoryId field on the Categories table (I am not sure this was correct to begin).
My expectations for the way the database would handle the table relationship: I didn't want the DB to do anything with the products table if I deleted a category out of the Categories table, or vise versa. The only thing would be that the category field in a Product would be blank (or default) if their category was removed.
Finally, do I have to do anything in my entity classes such as in the Products class, add the ProductId to the Category.ProductId?
Eventually, when I Orders and Users to the project, I can see a relationship where each user -> many orders -> each order has many products -> and each product is in one category.
But I am having a hard time understanding how or if I should be setting up a Foreign key relationship in the two current tables of Products and Categories and if so how to setup my entity class in relation to that FK.
Any advice.
It has been my experience (with L2S) that you don't want to specify any relationships between tables. I have simply done the PK, FK logic myself. This keeps the L2S generated objects simple and is most likely the way you worked with them before in SQL. That, at least, is the case for me.

Resources