【问题标题】:LINQ2SQL Entities - Updating only the fields that have changedLINQ2SQL 实体 - 仅更新已更改的字段
【发布时间】:2011-09-13 14:07:26
【问题描述】:

我希望在我的 MVC 3 项目中有一种更简单的方法来执行此操作。在我的数据库中,我有一个通过 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();
    }
}

我希望找到一种不那么繁琐的方法,用 customer 中不同的相应字段更新 newCustomer 中的字段。

有什么建议吗?谢谢。

【问题讨论】:

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


    【解决方案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 列来防止额外的数据库故障。

    【讨论】:

    • 我的代码进入附加方法但失败,返回“如果实体声明版本成员或没有更新检查策略,则只能附加为修改后的没有原始状态的实体。”错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    • 2013-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    相关资源
    最近更新 更多