实体框架 - 如何合并子集? (最佳实践) [英] Entity Framework - how to merge child collections? (Best Practices)

查看:100
本文介绍了实体框架 - 如何合并子集? (最佳实践)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我的应用程序的具体方案。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆