Entity Framework : updating one-many relationships for an entity's child collection - asp.net-mvc

Consider an application dealing with houses and pictures. An entity named House has a 1:n relationship to HousePicture.
The application allows the user to create and edit a House, and add/remove HousePictures.
[HttpPost]
public ActionMethod Edit(House h)
{
//get an attached entity from the DB first.
House original = db.Houses.SingleOrDefault(x=>x.ID==h.ID);
UpdateModel(original);
//collect all the uploaded pictures.
original.HousePictures = GatherPicturesFromForm();
db.SaveChanges();
// the changes for the House are saved,
//but child collection Pictures are not.
}
How do you go about updating - adding new & deleting - the child collection when recreating the child collection from scratch?
Add() or Attach() for each child in the collection?
In what sequence do you need to Add or Attach the parent entity vs. the child collection?
How to go about detecting the children to remove? Is this a feature of EF4 where deletes happen automatically by the framework, or does the developer need to write this logic?
When adding more than one HousePicture, its ID == 0. The entity has the primary key in SQL Server has an auto-assigned PK of int IDENTITY(1,1). This becomes a problem because EF4 thinks that 2+ child have the same ID.
What are your recommendations on saving child collections using Entity Framework 4?
Any other suggestions on making the persistence of 1:n collections easier when updating/adding/deleting?

In EF just add new objects to a collection and they'll automatically be persisted to the database with the correct foreign key values.
original.HousePictures.AddRange(GatherPicturesFromForm());

Related

Adding a record into an association table using Breezejs

Background Info
So I am using Breezejs and Knockout with EF5 and the Breeze MVC api controller on the backend. One of my tables in my data base is an association table, 3 columns - an id and two foreign keys(we'll call them fkey1 and fkey2 with table1 and table2). In my application, I need to add a record to this association table. Breeze knows about the relationships that this table has.
Situation
Breeze js makes a new record for me, then I find out the records I need to associate with it. Do I need to add in the id of the table1 entity into the fkey1 observable and the table2 entity id into the fkey2 observable AND add the whole entities into their respective relationship properties AND add push this new entity object into the table1 and table2 entities association property? Or does adding the id's into the new object automatically add those objects into the relationship properties (maybe those objects are subscribed to the fkey1 and fkey2 properties? - this is what I'm guessing happens in the background of breeze, a shot in the dark though I have no idea).
Creating new entities with Breeze is super easy and I love it, but I'm a little confused when it comes to creating new entities that have a lot of relationships.
Let me if you need a better description of my situation, it's kind of a tough thing to explain. Thanks!
Providing that you set the "foreign key" properties appropriately when creating and attaching entities, Breeze will automatically update all of the associated relationships, i.e. navigation properties on this and any related entities. You should never need to manually perform any fixup.
Similarly, if you do the reverse and assign an entity to a scalar navigation property then Breeze will automatically update the foreign key(s). For a collection navigation property, if you push a value into the collection then Breeze will automatically update the foreign key of the entity being pushed.
Hope this helps, but maybe I'm missing the question...

Performance implications : Entity table reference vs List of that table reference

I am using entity framework and developing an architecture for application with remote data access. Coming back to point, i query the database for one record (say on the basis of itemcode). Now the resultset i will get whether i should return it as List or collection or simple as an object of entity. I am using entity object but my boss is saying i should use List. He thought , returning result as an entity with return whole table structure also. Quick suggestion would be appreciated.
List<Employee> lstemployee = GetRecordByCode(itemCode)
or
Employee emp = GetRecordByCode(itemCode)
What's the difference? If itemCode is a unique key you will either get one Employee object or a list containing the same one Employee object. You will never return the whole table. That will only happen if within GetRecordByCode you do something like context.Employees.ToList() without any Where filter before the ToList().
If itemCode is not unique you even have to use a list.

Reassigning one-to-one relationship nulls previous object / CoreData iOS

I have 2 entities. ObjectA stores all ObjectB's objects through a many-to-many relationship. ObjectA also stores one specific object as a default object using a one-to-one relationship. The idea is to be able to assign many different child objects for EntityA while also keeping a specific reference to one specific child object. This idea works perfectly fine all throughout my project exempt in one circumstance(identical code and identical entity relationship setups.
The problem I am having is when I reassign the existing defaultObject to a new different object by simply ObjectA.defaultObject = someObject23; this assigns the new object correctly but in the process my original To-Many relationship reference to that existing defaultObject goes null.
The to-many relationship 'AllObjects' from EntityA has a Cascade delete rule for EntityB.
The One-To-One relationship 'DefaultObject' has a NULL delete rule for EntityB.
Both have inverses set.
Here is a real quick overview.
ObjectA.allObjects = 10 objects; // 1 of these is someObject1
ObjectA.defaultSomeObject = someObject1; // This works fine.
ObjectA.defaultSomeObject = someObject2; // This assigns the new defaultSomeObject=someObject2,
// but in the process it removes the someObject1 from my ObjectA.allObjects array (Goes NULL)
I'm stumped because like I say I have used this technique multiple times and the only workaround to this I have succeeded with is to "rig" it and actually save a reference to the previous object, delete it from the ObjectA array, set the new defaultObject, then write that object back to the array. There must be a simple explanation I am overlooking. More coffee? lol. Any help is greatly appreciated. I have tried all the different delete rules for each relationship as well just for kicks.
Problem solved. Definitely needed more coffee. What was happening was the one-to-one relationship was using the to-many relationship inverse causing it to do exactly what it was supposed to do, go null...

EF Code First - Entity joining multiple tables

I currently have an EF class that is backed by a database view (joining multiple tables). To make it updatable, I need to change the class to be backed by a database table. I am using Entity Framework 4.1 Code First and can't figure out how to set up those relationships?
To simplify, I currently have a Categories class that returns the Category Name (Categories table) and Category Type Name (CategoryTypes table). These are both in the database view that I currently use. I want to change to a ViewModel that brings back both of these fields directly from their tables and joins properly, that way when a user updates a Category Name, EF should be able to properly handle the update (since it will be updating the table instead of the view). Any tips on how to do this?
Table is a table - it is a single database object. If you want to remove your view and replace it with a table you need to delete your current tables (Categories and CategoryTypes) and create a single table which will contain denormalized data. That is pretty bad solution and it will cause you problems in the whole application.
Just to simplify description: It is not possible to replace your view constructed by joins among several tables with a table and it is not possible to make your view updatable.
You are doing it wrong because you are obviously mapping view models directly to your database. Map Catagories and CategoryTypes to entities load Category with its CategoryType and flatten them to your view model in your application logic (or load the view model through projection). Once user updates your view model decompose it back to separate entities and save them.

Linq2Sql Insert Records To Related Tables

Similar situation to : How to add several dependent records with LINQ2SQL
(this seems logical, but it doesn't work for me)
ASP.NET MVC + Linq2SQL
I have 2 tables called Challenges and Participants.
Challenge { challengeId,
ChallengeDesc, applicantId,
respondantId }
Participants { participantId, FirstName, LastName }
There are 1-many relationships between participants and Challenges - 1 for each key (applicantId, RespondantId).
I have an input form that collects all fields to create a new applicant and respondant and the challenge. The Databinder binds all the fields to Challenge and it's child participants correctly, however, the participant objects' names don't match the key names in the challenge object when browsing the structure created by Linq2Sql (applicantId matches with Participant object and respondantId matches with Participant1 object).
So when i try to SubmitChanges() after InsertOnSubmit(aChallenge) i get a foreign_key constraint validation message back from Linq2Sql. In SQL Server Profiler, I can see that the participants are being created properly, but when the challenge is being saved, the IDs of these newly inserted participants are not being set to the challenge object so the system is throwing a foreign key violation message.
How do i get past this?
You have to write it this way I think (assuming you have classes Participant and Challenge):
Participant applicant = new Participant();
Participant respondant = new Participant();
//update your participants here
Challenge insertedChallenge = new Challenge();
//update your challenge values here
applicant.Challenges.add(insertedChallenge);
respondant.Challenges1.add(insertedChallenge);
submitChanges();
Linq-to-SQL should automatically assign these properties (Challenges and Challenges) so it can set the key values for you.
Hope it helps.
You might want to edit you data objects (normally by using the DBML designer) and rename the Participant-typed properties to Applicant and Respondent respectively. It'll be easier to work with than having Participant and Participant1. You can do this in the association properties (the lines that connect the tables).
When you want to assign the foreign keys in Challenge, you have two choices. If you have the Participant objects themselves, you can assign them to the (newly renamed) Applicant and Respondent properties (and LINQ to SQL will update ApplicantID or RespondentID accordingly). Or if you have the ParticipantIDs, you can assign them to ApplicantID or RespondentID directly.

Resources