How to make "1-to-1" association works correctly in Entity Framework? - entity-framework

I have objects:
type A (Id, Name),
type B (AId, Description).
I want to make relation 1-to-1 (and create it 1-to-[0..1]). All works great exept deleting objects of type A. When I'm trying to delete some object from type A exception occurs.
A relationship is being added or deleted from an AssociationSet ‘...’. With cardinality constraints, a corresponding ‘...’ must also be added or deleted.
Im searched for solution (found editing CSDL for many-to-many), but nothing helps. There is also cascade action defined in the table in Database.
Any suggestions?
UPD: Thanks for answers.
Let's say more clear.
I don't want to implement inheretance betwen A and B
I try to fix problem by editing edmx file (like this http://codepolice.net/2008/12/16/cascade-delete-in-entity-framework/), but no luck. Seems it's only worked for one-to-many.
I just want to have 2 objects with one-to-one relation. For example, Order and OrderDetails. I expected automatic creating/deleting OrderDetails for every Order I have.

1:1 should give an exception if your deleting B right?
I think what you want is 0..1
Right click Add->associations.
under multiplicity:
On the left hand side choose One for A and 0 or 1 on the right for B.
I think you need this if you want an optional description object(B) for A.
You could also move B's fields into A and check not null for those fields right? That might be easier, then I think you could just use A's fields.
Also, I'm not a database designer by a long shot but, wouldn't you want the Data of A in A?
If for instance you had "Person" and his "Home", I would think those would be a good case for 1:1 (or 0..1 real world), because they themselves are 2 distinct objects that other objects can share independently.
Seems like the A_DataObjects just leads to an unnecessary join?
Old Answer below (not looking for inheritance, but leaving for someone else):
OK, I think I ran into this today. I think what you might want to do is define 2 classes as subclasses of a base class (entity). Right click and do add -> inheritance to get started. I didn't get this all working yet, but I think it involves specifying a field in the base, BaseType which can be used to key in on the derived classes.
http://mosesofegypt.net/post/Inheritance-and-Associations-with-Entity-Framework-Part-1.aspx
Note, there's a part 2 and 3 of this.
-David

One way to do this is to have a single entity that maps to 2 tables. See:
http://msdn.microsoft.com/en-us/library/bb896233.aspx

Visual EntityFramework tool doesn't recognize correctly 'on delete cascade' and creates incomplete xml mapping. You have to change edmx file (You can do it with notepad). Instructions here:
http://codepolice.net/2008/12/16/cascade-delete-in-entity-framework/
Worked for me.

Just make a one-to-many relationship, then by creating unique constraints on the foreign keys in the database you can force it to be 1:1. You can find a full tutorial about it here
(This uses Code-First)

Related

iphone core data: three tier Entity relationship confusion

Re the Core Data table below. I want to associate the "Color" entity with the "detailsColor" attribute (in the Details entity). The idea is that there are (in this case) three Colors applicable to detailsColor.
I would have thought the "Relationships" in Color would apply to the "detailsColor" attribute as these colors only apply there. I cannot seem to connect the two though. I can only create a relationship with the entire Details entity. Is this correct? Suggestions appreciated.
A relation connects entities, so it doesn't make sense to say that "colorDetails" applies "to the entire Details entity". Your set up looks okay to me.

I don't need/want a key!

I have some views that I want to use EF 4.1 to query. These are specific optimized views that will not have keys to speak of; there will be no deletions, updates, just good ol'e select.
But EF wants a key set on the model. Is there a way to tell EF to move on, there's nothing to worry about?
More Details
The main purpose of this is to query against a set of views that have been optimized by size, query parameters and joins. The underlying tables have their PKs, FKs and so on. It's indexed, statiscized (that a word?) and optimized.
I'd like to have a class like (this is a much smaller and simpler version of what I have...):
public MyObject //this is a view
{
Name{get;set}
Age{get;set;}
TotalPimples{get;set;}
}
and a repository, built off of EF 4.1 CF where I can just
public List<MyObject> GetPimply(int numberOfPimples)
{
return db.MyObjects.Where(d=> d.TotalPimples > numberOfPimples).ToList();
}
I could expose a key, but whats the real purpose of dislaying a 2 or 3 column natural key? That will never be used?
Current Solution
Seeming as their will be no EF CF solution, I have added a complex key to the model and I am exposing it in the model. While this goes "with the grain" on what one expects a "well designed" db model to look like, in this case, IMHO, it added nothing but more logic to the model builder, more bytes over the wire, and extra properties on a class. These will never be used.
There is no way. EF demands unique identification of the record - entity key. That doesn't mean that you must expose any additional column. You can mark all your current properties (or any subset) as a key - that is exactly how EDMX does it when you add database view to the model - it goes through columns and marks all non-nullable and non-computed columns as primary key.
You must be aware of one problem - EF internally uses identity map and entity key is unique identification in this map (each entity key can be associated only with single entity instance). It means that if you are not able to choose unique identification of the record and you load multiple records with the same identification (your defined key) they will all be represented by a single entity instance. Not sure if this can cause you any issues if you don't plan to modify these records.
EF is looking for a unique way to identify records. I am not sure if you can force it to go counter to its nature of desiring something unique about objects.
But, this is an answer to the "show me how to solve my problem the way I want to solve it" question and not actually tackling your core business requirement.
If this is a "I don't want to show the user the key", then don't bind it when you bind the data to your form (web or windows). If this is a "I need to share these items, but don't want to give them the keys" issue, then map or surrogate the objects into an external domain model. Adds a bit of weight to the solution, but allows you to still do the heavy lifting with a drag and drop surface (EF).
The question is what is the business requirement that is pushing you to create a bunch of objects without a unique identifier (key).
One way to do this would be not to use views at all.
Just add the tables to your EF model and let EF create the SQL that you are currently writing by hand.

How to tell what name RIA Services/EF Model uses for Associations?

I'm working on a C#.NET 3.5 WCF RIA Services app and having an issue with my Entity Framework model.
My entity Foo is mapped to a DB table and has a primary key called FooId. My Bar is mapped to a DB view. I've selectively designed this view to generate a composite key in the EF using two of the columns (by making sure they were non-nullable and the others are all nullable. This was done using NULLIF and ISNULL in the view design.)
I'm able to add this view to the model with no problem but I keep running into an issue when I try to map an association between the two. Foo should contain many Bars but I keep getting the following error when I add the association:
Unable to retrieve AssociationType for
association 'FK_Bar_Foo'
According to this page, it looks like this might work if I can properly name the association (since RIA Services looks for specific names.) I've tried several variants of names that match the pattern of other associations with no success. Does anyone know if there's a place I can look to find out what name it's looking for?
Thanks,
After some research I found a workaround to the issue here. The problem with this solution is that you have to repeat it every time the model is updated, which just won't work for me. It appears the current version of the EF doesn't support this type of relation.
The solution I finally went with was to redesign the client to independently call the service and request an entity collection by passing the primary key (FooId) of my Foo type. It's not the best approach (and requires a lot more manual coding) but it does the job. I hope Entity Framework version 4 solves this limitation.

Getting Error 3007 when I add my Entity Model

I am getting an error 3007 when I add my entity model to my solution.
I found these links:
Good explination
Short answer
About this error:
Error 1 Error 3007: Problem in Mapping
Fragments starting at lines 89, 94:
Non-Primary-Key column(s) [Person_ID]
are being mapped in both fragments to
different conceptual side properties -
data inconsistency is possible because
the corresponding conceptual side
properties can be independently
modified.
Their Answer: I agree with their conclusion that by simply deleting the Scalar Property Person_ID and leave the Navigation Property my problem is fixed. However this is not very scalable since I am dynamically building my database and my entity is updated very often. I dont want to have to go through and clean up my entity every time I update it.
My Question: Is there a way to fix the error by correcting the way EF builds the entity? Or is there a way to remove the Scalar Property through code? Perhaps there is even a few options that I am overlooking.
Try to remove foreign property column from Entity set using entity model design it will solve your problem
For example
We have two tables one is customer and other one is order, using entity model design we added association between customers and orders when we do this Ado.net entity framework i will add navigation properties to both below tables.
Like
Customer.Orders - Here order is list
Order.Customer
One - Many relation.
So we need to remove property from with name CustomerId[Foreign key column] from Order entity set.
For reference:
http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/2823634f-9dd1-4547-93b5-17bb8a882ac2/
My experience with EF v1 is similar to yours. When the EDM is generated incorrectly and you can't work around the issue, you have to manually edit the EDM. EF v.Next (Entity Framework v4 I believe) will support "Code Only" Entity Data Models, and the EDM designer is supposed to be much better. One or the other improvement should make our lives easier. Until then...

Inverse relationship warning - ask for practices on using inverse relationship

I have the Order table which contains information about a specific order, (when does it start, how many people, etc...) and that Order table has To-Many relationship to Menu Item table. I call that relationship "orderItems".
The compiler gives me warning, "Order.orderedItems -- to-many relationship does not have an inverse: this is an advanced setting (no object can be in multiple destinations for a specific relationship)"
How do you normally do for inverse relationship? Do I need to create a new relationship on the Menu Item to point back to Order, and set the inverse relationship to the "orderedItems"? (In fact, there is no reason for me to save that data in the Menu Item table)
Someone can explain to me why, or at least, point me the reason on why I need to create the inverse relationship on the Menu Item table.
Thanks in advance,
I ran into this warning and problem too! Here's what you need to know...
Lets say you have two tables - Cars and Drivers. You define a one-to-one relationship - one car to one driver, but no inverse.
So now, if you create a car and assign it a driver, if you delete the driver later, and then try and access car.driver, your program will crash. Car.driver will not be nil - it will crash your program.
So, if you don't create an inverse, you can't ever check to see if something is nil, and you can't even safely work with car.driver at all if driver has been deleted.
I don't like how XCode has this set up. It should default to inverse and be a pain in the ass to change it.
Setting up an inverse is simple. Just open your xcdatamodel in XCode, click the existing relationship, and check the inverse box.
Typically you should always add the inverse relationships.
Do not think about Core Data in terms of the tables that will be generated. In fact, Core Data is smart enough not to put the data in more than one table.
Focus on designing a data model that will meet your needs (and add the inverse relationships).