EF Code First Parent-Child insertions with identity columns - entity-framework

i have the following model.
class Parent
{
int ParentId (identity column) { get; set; }
string ParentName { get; set; }
virtual ICollection<Child> Children { get; set; }
}
class Child
{
int ChildId (identity column) { get; set; }
string ChildName { get; set; }
int ParentID { get ; set; } //foreign key to Parent(ParentID)
}
How do i insert few rows to my parent and child in single transaction? Basically i want to get the identity generated on the parent(say i insert a row in parent) and insert child rows with that value?
How this can be achieved using Code First?

You shouldn't worry about what value the Id of Parent will get in order to insert Child rows. This should be enough:
var parent = new Parent
{
// fill other properties
Children = new List<Child>()
}
parent.Children.add(new Child { /*fill values */);
dbContext.Parents.Add(parent); // whatever your context is named
dbContext.SaveChanges();
For the record, the ID's will be assigned after calling SaveChanges(), so if you really need the ID before inserting a Child entity you can always call SaveChanges() twice.
Again, this shouldn't be necessary though.
By the way, I would recommend making the Foreign Key property from Child to Parent a navigation property, so the Child class would look like:
class Child
{
public int ChildId { get; set; } // identity column
public string ChildName { get; set; }
public virtual Parent Parent { get ; set; } //foreign key to Parent
}
That way you can always access the Child's parent directly without having to retrieve it explicitly from the database yourself (it will be lazy loaded).

For an example of how to do this, see the new EF Code First MVC tutorial series. The 6th one in the series has an example of this. The first one in the series of 10 is here:
http://www.asp.net/entity-framework/tutorials/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application

Related

Linq to Select Parent Objects Where Child Objects Dont contain value

If I have a DB structure like this
class Parent {
int ID { get; set; }
string Name { get; set; }
List<Child> Children { get; set; }
}
class Child {
int ID { get; set; }
string Name { get; set; }
List<Parent> Parents { get; set; }
}
I want to get a list of all the Parents who have a child whos name is NOT "Dave"
So
If Parent one has two children called Jack and Jill, I want them
If Parent two has two children called Sam and Dave I dont want them
If Parent three has no children I want them
If Parent four has one child called Steve I want them
If Parent five has one child called Dave, I dont want them
I want to get a list of all the Parents who have a child whos name is NOT "Dave"
conflicts with Rule #3: If Parent three has no children I want them.
The requirement that fits all the rules can be described as:
get a list of all the Parents who have NO child WITH name "Dave"
which in LINQ translates as:
var query = db.Parent.Where(p => !p.Children.Any(c => c.Name == "Dave"));

Breezejs EF BeforeSaveEntities editting savemap

I'm trying to add some logic into the BeforeSaveEntities method.
On the client we can add a parent record and a number of child records before hitting save.
Our parent record has two fields which can be chosen by the user and are a sort of unique identifier (but not the id). The child record also has some unique identifiers and a total field. The classes look something like this:
public class Parent
{
public int Id { get; set; }
public int Ref1 { get; set; }
public int Ref2 { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public int Ref1 { get; set; }
public int Ref2 { get; set; }
public int Total { get; set; }
public int ParentId { get; set; }
[ForeignKey("ParentId")]
public Parent Parent { get; set; }
}
In the BeforeSaveEntities I'm trying to check if a parent record with the Ref1 and Ref2 fields the same as the added entity using a second context.
If a parent record exists, I remove it from the savemap to prevent it from being re-added (this seems to work).
I then look at the child records being added (again by querying a second context), and what I'm trying to do is allow the new record to be added by leaving them in the savemap where they don't exist (but updating the parentid to link them to the existing parent record).
If a child record already exists, I want to increment the total of the existing record by the value in the added one in the savemap.
I've tried a couple of ways, but can't seem to get it working. It always seems to result in all child entries for the parent getting added again, even if there is only one new child entity in the savemap.
Apologies for the contrived classes, but hopefully this gives enough info to convey what I'm trying to do.

Entity Framework - Add an item to a list more than once

I am creating an Entity Framwork Code First app and am running into a problem when trying to add an entity to a list more than once.
I have the following two classes, which reference each other for a many-to-many relationship.
public class Order
{
public virtual List<OrderItem> OrderItems { get; set; }
}
public class OrderItem
{
public virtual List<Order> Orders{ get; set; }
}
This creates a the following three tables in my database:
Orders
- OrderId (PK, int)
.
OrderItems
- OrderItemId (PK, int)
.
OrderOrderItems
- Order_OrderId (PK,FK,int)
- OrderItem_OrderItemId (PK,FK,int)
In code, I wish to do the following:
private void AddOrderItemsTest
{
OrderItem orderItem = GetOrderItem(); // gets an existing order item from the DB
var order = new Order();
order.OrderItems.Add(orderItem);
order.OrderItems.Add(orderItem); // add the order item to the list a second time
context.Orders.Add(order);
}
When this gets persisted to the database, only a single orderItem entity is added to the list. We see in the table OrderOrderItems that OrderItem_OrderItemId is a PK and therefore must be unique. This means that EF has designed the tables in a way that won't allow more than one orderItem of the same type to be added to the list more than once.
Is there a Data Annotation that I can add to tell EF to allow me to add more than one item of the same type to the list?
I believe that it is not correct way of handling item count (of same item) in your order. Do you really want 10000s duplicated entries loaded into your OrderItems collection? I guess not.
You will need different primary key on OrderOrderItems table, hence suggest to introduce new entity that will contain OrderItem amount per Order:
public class OrderItemDetails
{
public int OrderItemDetailsId { get; set; }
public int OrderId { get; set; }
public int OrderItemId { get; set; }
public int Amount{ get; set; }
public virtual Order Order { get; set; }
public virtual OrderItem OrderItem { get; set; }
}
public class Order
{
public virtual List<OrderItemDetails> OrderItemDetails { get; set; }
}
public class OrderItem
{
public virtual List<OrderItemDetails> OrderItemDetails { get; set; }
}
And if you not happy with introducing Amount and still want to have duplicated entries per each item instance that will be absolutely fine because primary key of your many to many relation will be not combination of OrderId and OrderItemId but OrderItemDetailsId.

Navigation Property to 'Child object' in 'Parent child collection' on 'Parent'

Is there any way to save a child object in a parents child object collection and also setting it to a navigation property on the parent without round tripping to the database? example below doesn't work
public class Parent
{
int Id { get; set; }
int? ChildId { get; set; }
Child Child { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public class Child
{
int Id { get; set; }
public Parent Parent { get; set; }
}
....
var p = new Parent();
var c = new Child();
p.Child = c;
p.Children.Add(c);
Context.Set<Parent>().Add(p);
Context.SaveChanges();
EDIT
The example above throws this error when 'savechanges()' is called.
Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values.

Return Only Child Entity Linq Entity Framework

Given something like:
public class Parent
{
public int Id { get; set; }
public List<Child> Children { get; set; }
}
// There is no reference to the parent in the object model
public class Child
{
public int Id { get; set; }
public string MyProperty { get; set; }
}
is it possible to load only a child matching a particular condition, for a given Parent ID, without also loading the parent entity?
I have seen solutions that use projection to load the parent and zero or more children matching a condition.
If I understand you correctly, this should do it; it puts the conditions you want on both the parent and child, but selects only the child.
from parent in db.Parents
from child in parent.Children
where parent.Id = 4711 &&
child.MyProperty == "olle"
select child;