LINQ2SQL Entities - Обновление только тех полей, которые были изменены - PullRequest
2 голосов
/ 13 сентября 2011

Я надеялся, что в моем проекте 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 соответствующими полями в customer, отличающимися.

Есть предложения? Спасибо.

1 Ответ

1 голос
/ 13 сентября 2011

Я думаю, что вы можете реализовать 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 в вашем коде).Взгляните на здесь , здесь и определенно здесь , чтобы увидеть, как можно использовать столбцы TimeStamp для предотвращения дополнительного отключения базы данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...