考慮下面的表格(在截圖FK從位置到客戶是不可見的,但它的存在,只是沒有刷新...):實體框架:遞歸更新父子給我複製
我的映射:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>().ToTable("CUSTOMERS");
modelBuilder.Entity<Customer>().HasKey(c => c.Id).Property(c => c.Id).HasColumnName("CUSTNO");
modelBuilder.Entity<Customer>().Property(c => c.Name).HasColumnName("NAME");
modelBuilder.Entity<Customer>().HasMany(c => c.AllLocations).WithRequired(l => l.Customer).Map(x => x.MapKey("CUSTNO"));
modelBuilder.Entity<Customer>().Ignore(c => c.RootLocations);
modelBuilder.Entity<Location>().ToTable("LOCATIONS");
modelBuilder.Entity<Location>().HasKey(c => c.Id);
modelBuilder.Entity<Location>().Property(c => c.Id).HasColumnName("ID");
modelBuilder.Entity<Location>().Property(c => c.LocationCode).HasColumnName("LOCATION_CODE");
modelBuilder.Entity<Location>().HasMany(l => l.Children).WithOptional(ch => ch.Parent).Map(x => x.MapKey("PARENT_ID"));
modelBuilder.Entity<Product>().ToTable("PRODUCTS");
modelBuilder.Entity<Product>().HasKey(p => new { p.Partno, p.LocationId, p.Quantity, p.SellUnit });
modelBuilder.Entity<Product>().Property(p => p.Partno).HasColumnName("PARTNO");
modelBuilder.Entity<Product>().Property(p => p.LocationId).HasColumnName("LOCATION_ID");
modelBuilder.Entity<Product>().Property(p => p.PartDescription).HasColumnName("PART_DESCRIPTION");
modelBuilder.Entity<Product>().Property(p => p.Quantity).HasColumnName("QUANTITY");
modelBuilder.Entity<Product>().Property(p => p.SellUnit).HasColumnName("SELL_UNIT");
modelBuilder.Entity<Product>().HasRequired(p => p.Location).WithMany(l => l.Products).HasForeignKey(p => p.LocationId);
}
而且我的更新代碼:
public void UpdateLocations(string customerId, IEnumerable<Location> locations)
{
using (var context = new CustomerWarehouseContext(connectionString))
{
foreach (var location in locations)
RecursiveUpdate(location, context);
context.SaveChanges();
}
}
private void RecursiveUpdate(Location location, CustomerWarehouseContext context)
{
if (location != null)
{
bool locationIsNew = location.Id.Equals(Guid.Empty);
if (locationIsNew)
{
location.Id = Guid.NewGuid();
context.Locations.Add(location);
}
else
{
context.Entry(context.Locations.Single(l => l.Id.Equals(location.Id))).CurrentValues.SetValues(location);
}
if (location.Children != null)
{
foreach (var childLocation in location.Children)
{
childLocation.Parent = location;
RecursiveUpdate(childLocation, context);
}
}
if (location.Products != null)
{
foreach (var product in location.Products)
{
if (locationIsNew)
{
location.Products.Add(product);
}
else
{
//How to update product when key is changed? I cannot use contex.Entry here?
}
}
}
}
}
我執行下面的代碼:
Customer customer = null;
using (var context = new AwesomeContext("myAwesomeConnectionString"))
{
customer = (from c in context.Customers.Include(c => c.AllLocations.Select(l => l.Products))
where c.Id.Equals("100100")
select c).FirstOrDefault();
}
Location locationToUpdate = customer.RootLocations.Single(l => l.Id.Equals(Guid.Parse("1a2ad52e-84cc-bf4c-b14d-dc57b6d229a6")));
locationToUpdate.LocationCode = "Parent " + DateTime.Now.Millisecond; //Goes OK
locationToUpdate.Children[0].LocationCode = "Child " + DateTime.Now.Millisecond; //Goes OK
locationToUpdate.Children[0].Products[0].Quantity = 200;
locationToUpdate.Children.Add(new Location() { LocationCode = "XXX", Customer = customer, Parent = locationToUpdate }); //Creates duplicates?
UpdateLocations(customer.Id, newList);
所以,我改變了家長和孩子的位置代碼,在孩子的位置更新產品的產品數量。數量是產品表的關鍵部分。 另外,我正在向父級添加一個新位置。
問題:
- 我如何更新我的產品?因爲我改變了部分關鍵字,所以我無法使用context.Entry(...)來檢索舊的。
- 爲什麼在添加第二個子位置後,我的上下文中有重複的客戶/位置?我最終有5個地點和2個客戶,而不是3個地點和1個客戶,所以它給了我一個PK例外。不知怎的,它在將一個孩子添加到某個位置後創建了一個新客戶。所以它有一個擁有2個位置的客戶實體,以及一個擁有3個位置的實體。爲什麼???
那麼這個作品,但它也標誌着我所有更新的位置爲不變。此外,當一個客戶的財產已經改變它不會更新這個:-( –