Лучший способ обновления в Linq To SQL - PullRequest
6 голосов
/ 20 марта 2009

У меня есть несколько классов сущностей, которые я использую для анализа текстовых файлов фиксированной ширины, а также для использования Linq to SQL. Я использую эти классы для анализа данных из указанных текстовых файлов и сравнения с данными в базе данных.

У одного из этих объектов много свойств, и я не хочу тратить время на настройку каждого отдельного свойства в объекте результата Linq.

Есть ли способ сказать Линку "Вот мой объект, используйте его для обновления записи"? Вот код, над которым я работаю:

if (partialContent.MonthlyAddChange == "A")
   {
       bookContentTable.InsertOnSubmit(partialContent);
   }
   else if (partialContent.MonthlyAddChange == "C")
   {
       var query = from bookContent in bookContentTable
                   where bookContent.EAN == partialContent.EAN
                   select bookContent;

       if (query != null)
       {
           // Do something with query.First()
       }
   }
}

В этом случае лучше удалить запись и выполнить InsertOnSubmit ()?

Ответы [ 5 ]

2 голосов
/ 20 марта 2009

Я думаю, что концепция редактирования записи отличается от удаления и вставки новой. По сути, я думаю, что ORM должен абстрагироваться от генерации первичного ключа и других связанных вещей. Удаляя и вставляя, вы, возможно, удаляете целостность записи (возможно, выдаете новый первичный ключ, делая ссылочные объекты недействительными и так далее ...) Я предлагаю обновлять запись всякий раз, когда предпринимаемое вами действие является концептуально обновлением .

1 голос
/ 23 марта 2009

В этом случае лучше удалить запись и выполнить InsertOnSubmit ()?

Нет, определенно нет - просто учитывайте ссылочную целостность, которую должен использовать любой хороший, стабильный дизайн БД. Если ваша запись уже используется другими строками, вы не можете просто удалить ее и вставить заново - вы нарушите эти ограничения целостности.

Если вы просто меняете несколько значений, обновите существующую строку - намного проще и гораздо более согласованно.

Марк

1 голос
/ 21 марта 2009

Вы можете использовать autopper, чтобы скопировать значения для вас. Проверьте это для получения дополнительной информации: http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/01/22/automapper-the-object-object-mapper.aspx

1 голос
/ 21 марта 2009

Я думаю, что вы можете использовать что-то вроде DataContext.Table.Attach (record, true), а затем DataContext.SubmitChanges (). Но я не совсем понял это ...

Итак, я сделал тест. Это будет работать, только если вам не требуется проверка параллелизма (т. Е. Только вы обновляете таблицу).

Вот мой стол

People
PersonID int
FirstName varchar(50)
LastName varchar(50)

Я заполнил таблицу следующей записью

> PersonID     FirstName    LastName
> 1            Jason        Punyon

Я создал LINQ2SQL DataContext только с этой таблицей PeopleDataContext, и для каждого свойства класса People я установил для свойства UpdateCheck каждого свойства записи значение Never.

Вот код:

static void Main(string[] args)
{
    var p = new People();
    p.PersonID = 1;
    p.FirstName = "Jason";
    p.LastName = "This is a new last name";


    using (var db = new PeopleDataContext())
    {
        db.Peoples.Attach(p, true);
        db.SubmitChanges();
    }
}

И это успешно работает. Никаких размышлений или чего-то еще, но, как я уже сказал, вы теряете проверку параллелизма.

0 голосов
/ 20 марта 2009

Я бы не стал удалять / воссоздавать. Предполагая, что два объекта имеют один и тот же интерфейс по отношению к свойствам, которые вы хотите обновить, я бы использовал отражение и скопировал значения изменения в существующий объект. Если какое-либо из значений отличается от исходного, запись будет помечена как нуждающаяся в обновлении, и SubmitChanges позаботится об этом.

Например (с небольшой проверкой ошибок):

 foreach (var bookInfo in bookContent.GetType().GetProperties())
 {
     var partialInfo = partialContent.GetType().GetProperty( bookInfo.Name );
     if (partialInfo != null)
     {
         bookInfo.SetValue( partialInfo.GetValue( partialContent, null ) );
     }
 }

Если вы знали, что это один и тот же тип, вы могли бы повторно использовать первый PropertyInfo вместо получения нового для частичного содержимого.

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