In my project I have entity model that looks like:
public class OrdersDbContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<OrderPosition> OrderPositions { get; set; }
}
public class Customer
{
public Guid Id { get; set; }
public virtual Order LiveOrder { get; set; }
}
public class Order
{
public Guid Id { get; set; }
public virtual IList<OrderPosition> Positions { get; set; }
public string Name { get; set; }
}
public class OrderPosition
{
public Guid Id { get; set; }
public int Price { get; set; }
}
And I need to provide a method that will update some Customer's properties as well as his LiveOrder and all OrderPositions (Insert new, update existing and delete old). I tried to do it in several ways, but all of them failed:
- Delete order and order positions and than insert new failed with
- Duplicate key exception. Detatch order and than attach updated - failed with:
Attaching an entity of type 'OrderPosition' failed because another entity of the same type already has the same primary key value.
What is the right way of doing it?
Full console program that demonstrate the issue:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
public class OrdersDbContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<OrderPosition> OrderPositions { get; set; }
}
public class Customer
{
public Guid Id { get; set; }
public virtual Order LiveOrder { get; set; }
}
public class Order
{
public Guid Id { get; set; }
public virtual IList<OrderPosition> Positions { get; set; }
public string Name { get; set; }
}
public class OrderPosition
{
public Guid Id { get; set; }
public int Price { get; set; }
}
class Program
{
static void Main(string[] args)
{
var parentId = Guid.NewGuid();
var childId = Guid.NewGuid();
using (var ctx = new OrdersDbContext())
{
var agg = new Customer{
Id = Guid.NewGuid(),
LiveOrder = new Order
{
Id = parentId,
Name = "First order.",
Positions = new[] { new OrderPosition { Id = childId, Price = 3 } }
}};
ctx.Customers.Add(agg);
ctx.SaveChanges();
}
var newParent = new Order
{
Id = parentId,
Name = "Updated order.",
Positions = new[] { new OrderPosition { Id = childId, Price = 5 } }
};
try
{
using (var ctx = new OrdersDbContext())
{
var agg = ctx.Customers.First(x => x.LiveOrder.Id == parentId);
ctx.OrderPositions.RemoveRange(agg.LiveOrder.Positions);
var parent = agg.LiveOrder;
agg.LiveOrder = null;
ctx.Entry(parent).State = EntityState.Detached;
Console.WriteLine(ctx.Entry(parent).State);
ctx.Entry(newParent).State = EntityState.Modified;
agg.LiveOrder = newParent;
ctx.SaveChanges();
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}
}