LINQ2SQL实体 - 仅更新已更改的字段

时间:2011-09-13 14:07:26

标签: asp.net-mvc-3 linq-to-sql

我希望在我的MVC 3项目中有更简单的方法。在我的数据库中,我有一个Customer表,它通过LINQ2SQL映射到我的应用程序中。还有一个部分客户类,我在那里执行更新,查找等 - 我有这样的更新方法:

public static void Update(Customer customer)
{
    if (customer == null)
        return;

    using(var db = new DataBaseContext)
    {
        var newCustomer = db.Customers.Where(c => c.customer_id = customer.customer_id).SingleOrDefault();

        if(newCustomer == null) 
            return;

        newCustomer.first_nm = customer.first_nm;
        // ...
        // ...  Lot's of fields to update
        // ...
        newCustomer.phone_num = customer.phone_nm;

        db.SubmitChanges();
    }
}

我希望找到的是一种不太麻烦的方法来更新newCustomer中的字段,其中客户中的相应字段是不同的。

有什么建议吗?感谢。

1 个答案:

答案 0 :(得分:1)

我认为你可以实施IEqualityComparer

public class Customer
{
    public string first_nm { get; set; }
    public int phone_num { get; set; }
}        
class CustomerComparer : IEqualityComparer<Customer>
{
    public bool Equals(Customer x, Customer y)
    {
        //Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        //Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        //Check whether the customer' properties are equal.
        return x.first_nm  == y.first_nm && x.phone_num == y.phone_num ;
    }
}

并按如下方式执行:

if (newCustomer != customer)
{
    myDbContext.Customers.Attach(customer,true); // true means modified.
}  

或实施ICloneable并将newCustomer设为customer.Clone()。然后无需附加customer,因为newCustomer已经附加。

在EF(4.1)中,我认为你只需将实体附加为修改后的实体:

  myDbContext.Customers.AttachAsModified(customer, this.ChangeSet.GetOriginal(customer), myContext);

<强>更新
好吧,似乎L2S需要实体的原始值。在回复您的评论时,您有两个选择:使用时间戳列,返回实体子集或手中拥有原始实体。在您的方案中,您已拥有原始实体:

// This is your original entity
var newCustomer = db.Customers.Where(c => c.customer_id = customer.customer_id).SingleOrDefault();  

所以你很可能会这样做:

if (customer != newCustomer)
{
     myDbContext.Customers.Attach(customer, newCustomer);
}  

注意:如果我是你,我会将newCustomer重命名为originalCustomer,因为它与实体的状态更相关。

这种方法的问题在于您需要额外访问数据库以获取原始客户(代码中为newCustomer)。请查看herehere和明确here,了解如何使用TimeStamp列来防止额外的数据库访问。