实体框架 - 如何合并子集? (最佳实践) [英] Entity Framework - how to merge child collections? (Best Practices)
问题描述
以下是我的应用程序的具体方案。
Following is the exact scenario in my application.
有两个实体:
- 客户:客户ID,客户名称
- CustomerAddress:AddressId,客户ID(FK),区,市
有一个客户有一个一对多的关系与CustomerAddress。 客户可以有多个城市的地址。
A customer has one-to-many relation with CustomerAddress. A customer can have addresses of more than one cities.
当我将更改保存到现有的客户 - 在那个时候,它的基本CustomerAddress收集将是具有一个特定城市的各个地址只。
When I save changes to the existing customer - at that time, its underlying CustomerAddress collection will be having all addresses of one particular city only.
所以,当我更新的客户数据库中,它应该 -
So when I update that customer in the database, it should -
- 加入了城市的各个新地址的客户(例如:一个存在于集合,但不是以dB为顾客)
- 在保留那些是常见的两种 地址
- 删除所有那些存在于数据库中,但不是在收集该城市的位置。
我知道一种方法,其特征在于,我可以从数据库中获取客户的实体,可以添加,删除,通过地址收集循环有保留。
I know one method, wherein I can fetch Customer entity from database, and can add, delete, retain by looping through Addresses collection there.
但我更想知道的最佳实践来实现这一目标。
But I am more interested in knowing the best practices to achieve this.
在这么多的AP preciated任何想法?
Any idea on this much appreciated?
推荐答案
这就是我通常做,就像你说的,通过儿童导航循环,这意味着加载一切到内存单次往返,然后处理逻辑在应用程序中,这就是我们使用ORM的主要原因。
This is what I normally do, just like you said, looping through child navigations, that means loads everything into memory with a single round trip and then process the logic in the application, that's the main reason we use ORM.
// Loads contacts.
if (customerDb.Id != Guid.Empty)
{
context.Entry(customerDb).Collection(c => c.customercontactxrefs).Load();
foreach (var xref in customerDb.customercontactxrefs)
{
context.Entry(xref).Reference(x => x.contact).Load();
}
}
// Deletes missing contacts.
var deletedXrefs = customerDb.customercontactxrefs.Where(xrefDb => !customer.Contacts.Any(contact => xrefDb.ContactId == contact.Id)).ToArray();
foreach (var xref in deletedXrefs)
{
customerDb.customercontactxrefs.Remove(xref);
context.Set<customercontactxref>().Remove(xref);
}
// Edits existing contacts.
foreach (var xrefDb in customerDb.customercontactxrefs)
{
var foundContact = customer.Contacts.FirstOrDefault(contact => contact.Id == xrefDb.ContactId);
if (foundContact != null && xrefDb.contact != null)
{
xrefDb.contact.Name = foundContact.Name;
xrefDb.contact.Phone = foundContact.Phone;
xrefDb.contact.Mobile = foundContact.Mobile;
xrefDb.contact.Fax = foundContact.Fax;
xrefDb.contact.Email = foundContact.Email;
}
}
// Adds new contacts.
var newContacts = customer.Contacts.Where(contact => contact.Id == Guid.Empty).ToArray();
foreach (var contact in newContacts)
{
customerDb.customercontactxrefs.Add(new customercontactxref
{
Id = Guid.NewGuid(),
contact = new contact
{
Id = Guid.NewGuid(),
Name = contact.Name,
Phone = contact.Phone,
Mobile = contact.Mobile,
Fax = contact.Fax,
Email = contact.Email
}
});
}
或
using (RSDContext context = new RSDContext())
{
var details = order.OrderDetails;
order.OrderDetails = null;
context.Entry(order).State = EntityState.Modified;
foreach (var detail in details)
{
if (detail.Id == 0)
{
// Adds.
detail.OrderId = order.Id;
context.Entry(detail).State = EntityState.Added;
}
else if (detail.IsDeleted)
// Adds new property called 'IsDeleted'
// and add [NotMapped] attribute
// then mark this property as true from the UI for deleted items.
{
// Deletes.
context.Entry(detail).State = EntityState.Deleted;
}
else
{
// Updates.
context.Entry(detail).State = EntityState.Modified;
}
}
order.OrderDetails = details;
context.SaveChanges();
}
这篇关于实体框架 - 如何合并子集? (最佳实践)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!