Entity Framework 4 - how to Delete from many-to-many relationships - entity-framework

Please can you help me to enable the deleting of books from my database?
I am using EF 4 and have a many-to-many relationship between books and authors. When I try to delete a book, I get the following:
he DELETE statement conflicted with the REFERENCE constraint "FK_BookAuthor_Book". The conflict occurred in database "C:\PROGRAM FILES\MICROSOFT SQL SERVER\MSSQL10.SQLEXPRESS\MSSQL\DATA\NTCODING.MDF", table "dbo.BookAuthor", column 'BookAuthor_Author_Id'.
The statement has been terminated.
Being a SQL guru is not what I do, but I think it is telling me that there is a record in the join table that also needs to be deleted. I'm not sure which property I need to set or what bit of coding I need to add.
If you can help me with this I would be really appreciative.
Thanks in advance
Nick

When you create the foreign key relation between the table book and the table lying between book and author (the one that breaks the many-to-many relationship in two one-to-many relationship), try to specify the "cascade" action at "insert and update specification". The same for the link between authors and the middle table. Thus, when you try to delete an author (or a book), all the dependent records from the middle table will be deleted.

Looks like my sql knowledge wasn't too bad. I hoped that by removing the authors from the book's collection of authors the join table would remove the records....a la fantastico!
I had to do this in the controller action of my web application because I use a generic repository and do not cast it to a book in there. So if you do know a way I could enforce this rule in my repository instead, that would be useful still.
Thanks

Related

Update edmx after adding additional column to junction table

I'm using .Net 4.5, entity framework 5, database first. I have a junction (many-to-many) table in my database. For this example lets say the table is "StudentsCourses":
Students
-PkStudentId
-Name
Courses
-PkCourseId
-CourseNumber
StudentsCourses
-FkStudentId
-FkCourseId
This works just fine right now. The 'generate model from database' creates a Student entity with a navigation property to the Course entity. But here is where the trouble is:
I need to add another column to the StudentsCourses table. Lets just call this column "CourseYear". So our junction table would now look like this:
StudentsCourses
-FkStudentId
-FkCourseId
-CourseYear
So, I've added this column to the database and ran "Update Model from Database" on the edmx. I would expect to see an entity created for StudentCourses, with a navigation property to both Students and Courses. But no such entity is created. I still see the same two tables (Students & Courses) with the same navigation property as before.
I've done a lot of reading and researching, but haven't really come across a clear-cut answer. There is a wealth of information on code-first which I can't apply to my scenario. Is there a way to get what I'm after? Is it as simple as adding a PkId to the StudentCourses table? SQL Replication is preventing me from doing this. I would think the composite should suffice, but maybe EF needs a PK to do it's magic? I read a little bit about manually setting relationships, but could not find anything speaking to my particular situation. It could be that I am just missing a simple step in the process of updating the edmx from database. I've done this plenty of times when: adding new tables, adding columns, deleting columns, etc. I'm following the same steps as I always do, but maybe I need to do something different in this case?
Thanks ahead of time for any help. It is greatly appreciated. Please let me know if any more information would help.
From what I've gathered it appears as though EF will not generate a model for a table that doesn't have a Primary Key.
I'm a bit late for this, but you have the answer in this thread Updating Entity Framework Model after adding a field to a previous look up only table
As they say here, you have to delete the relationship between Students and Courses in the designer. Then update your model from the database, and make sure StudentsCourses table is checked in the Tables branch of the Add tab.

Why does entity framework skip one of my tables?

Entity framwork made a entity for each of my tables except for one, and I'm not sure why. I select it when i generate it from the database.
Here is my entity framework diagram, and the diagram in SQL:
http://imgur.com/a/zY17T
Notice how RecipeMeal is missing from entity framework. Does anyone have an idea why this might be happening?
RecipeMeal is supposed to store if a recipe is breakfast, lunch etc. It's not a column of Recipes because a recipe could be a lunch OR dinner recipe, as an example.
I am using EF 5.0
Thanks.
Entity Framework has built-in support for many-to-many relationships.
The table is exposed through the two ICollection<T> properties in Meal and Recipe.
I also found that if your table doesn't have a primary key it will also get skipped. One of my tables was just a summary table and didn't really need a primary key and it wouldn't be included in the reverse engineer. As soon as I added a primary key it was picked up.

How to decide a Primary Key from an Entity Collection programmatically

I'm encountering some problems importing my DB on Entity Framework. Some relationship between tables returns me some other entities without any primary key.. For my application I need to have a PK for every table.
Is there any way to say something like:
MyEntityCollection.SetKey("ColumnName")
Or something like that?
Thank you very much!
Take a look here, i discuss this in this answer,
EF4 Unknown Column In Field List
http://xhalent.wordpress.com/2011/01/21/configuring-entity-framework-4-codefirst/ has some detail around the two ways in EF4 of specifying a FK

Lack of a many-to-many linking table in EF 4.0 a bug or a feature?

I have a comment and a question. Entity Framework 4.0 does not show the linking table in a many-to-many relationship between two tables, such as shown in Northwind for “Order_Details”, a linking table between Orders and Products, if only two columns, both primary keys, are used in the linking table, as is often the case. So in Northwind if you use as primary keys both OrderID and ProductID in the Order_Details linking table between Orders and Products, for the many-to-many relationship, the linking table will not show up if only these two columns (primary keys) are present in Order_Details.
Consequently, you cannot Insert or Create in a many-to-many relationship linking table, because Entity Framework 4.0 does not show the linking table Order_Details nor does Intellisense show this linking table of the many to many relationship. How is one to then do an insert or update in the linking table if EF 4 does not show the hidden linking table? Arguments such as 'you must now start thinking in OOP' do not impress me. SQL has a certain structure and OOP is just an interface for it so we can use LINQ-to-entities rather than the clumsier SQL queries, IMO.
The trick to get around this bug was suggested for Silverlight here, http://forums.silverlight.net/t/159414.aspx/1 , and it works for web services and any other .NET solution: simply add, in your linking table, a dummy column of any type.
Now delete your original .edmx file, and rebuild a new one by generating it against the actual database.
Then intellisense shows the linking table, and then you can Insert / Create and do other normal oprations.
For example, Intellisense in EF 4.0 will now show the linking table Order_Details, and you can create or insert such as (partial fragment,omitting try/catch and any rollback options):
using (aDBEntity context = new aDBEntity())
Order_Details newOrdDetails = new Order_Details();
newOrdDetails.OrderID = //some number here
newOrdDetails.ProductID = //some number here
context.AddToOrder_Details(newOrdDetails);
context.SaveChanges();
Question: is this lack of showing a many-to-many linking table a bug or a feature of EF 4.0?
Personally, I think the linking table is not needed if you don't have any additional column other than two keys in it. I have never needed to access to the link table which is just used to define M2M relationship. I feel relaxed with adding relation between Foo and Bar by getting Foo (or Bar) first and use Foo.Bars.Add(sampleBar).
I think you answered your question. If you think OOP, this is a feature. If you want to have access to the link table (and you think you're doing it the right way), this is a lack of feature.

How do I cascade deletes into a link table using the EF4 fluent API?

I have two tables in an existing (MSSQL 2008 R2) database that are related by a link table.
The two tables are "Plan" and "Tips". The link table is "PlanTipLinks".
Plans can have many tips, and tips can be associated with multiple plans (i.e. it's a many-to-many relationship). In the application, I only care about the "Plan.Tips" relationship. I don't need the Tip.Plans inverse relationship.
The foreign key references in the link table cannot be null.
I'm using the following fluent API code to map this relationship:
modelBuilder.Entity<Plan>()
.HasMany(p => p.Tips)
.WithMany()
.Map("PlanTipLinks", (p, t) =>
new
{
PlanId = p.Id,
TipId = t.Id
});
This create the correct entries in the table. Problem is that, when I delete a plan, I get a foreign key exception on the PlanTipLinks table.
Presumably I need to tell it to cascade into the PlanTipLinks table when a plan is deleted, but I'm not sure how to do that. I don't seem to be able to call the WillCascadeOnDelete method using the HasMany/WithMany methods.
What am I missing here?
As of EF CTP4, there is no way to directly turn on cascade deletes on Many to Many associations by Fluent API.
That said, if your intention is to make sure that you can delete the principle (e.g. a Plan record) without having to worry about the dependent record in the link table (i.e. PlanTipLinks) then you don't need to turn on cascades on the database since EF Code First will take care of the cascade deletes on the client side when it comes to Many to Many associations.
For example, when you delete a Plan object, code first is smart enough to first send a delete statement to get rid of the dependent record in the PlanTipLinks table and after that it will send another delete statement to delete the Plan record.
For more info, please take a look at the following post:
EF CTP4 cascade delete on many to many relationship