Denis Gladkikh

outcoldman

My personal blog about software development

  • 30 Apr 2009
  • .NET, C#, Linq-To-SQL

Хочу рассказать немного о Linq-To-Sql тем, кто его еще не использовал, но есть идеи использовать в будущих проектах (а так же может услышать некоторые комментарии о том, как еще можно с ним работать). Так сказать - пару слов о том, как необходимо разработать архитектуру приложения, чтобы безболезненно использовать DLinq.

У меня был до знакомства с Linq-To-Sql небольшой опыт с ORM системой NHibernate, поэтому как должна выглядеть полноценная ORM я представляю. Сразу скажу, что Linq-To-Sql не является полноценной ORM, а скорее просто представление в объектах записей таблиц. Сделать объекты как захочется не получиться (не похожие по своей сущности на маппинные объекты базы данных), а исходить надо будет как раз от реляционной структуры (с некоторыми оговорками).

Итак, думаю всем известно как можно работать с DLinq. Если у нас есть созданная модель ModelDataContext с объектами Entities, то вот пример загрузки объекта

using (ModelDataContext dataContext = new ModelDataContext())
{
  Entity obj = (from e in dataContext.Entities
        where e.EntityID = 10
        select e).FirstOrDefault();
}

Дальше мы работаем с объектом obj, и в какой то момент нам нужно сохранить измененные данные. Как это сделать? В полноценных ORM системах есть возможность использовать методы Detach и Attach, смысл их простой, отцепляем объект от первого DataContext и покручиваем к другому. В DLinq метод Attach есть, а вот Detach-а нету, из-за чего нам приходиться подгружать объект заново в ModelDataContext и выставлять изменения ему (так сказать по каждому свойству). Может быть и другой вариант: клонировать объект, тогда он не будет зависеть от предыдущего ModelDataContext, НО, тогда, если есть у этого объекта ссылки на другие объекты, то с ними тоже нужно будет что то делать.

Можно делать и по другому. Работать с длинными сессиями - ModelDataContext открывать на задачу, например: загрузка, отображение объекта, и его сохранение, и только потом вызывать Dispose у ModelDataContext. Данный метод освобождает нас от повторных подгрузок объекта. Но возникнут другие сложности - если жизнь ModelDataContext будет разрастаться, скажем вы будете теперь держать открытым ModelDataContext на загрузку списка объектов, выбор одного из объектов, редактирование одного из объектов, добавление, удаление, то в случае, когда у вас будет вываливаться ошибки в базе данных (к примеру, невозможно удалить, потому как на него ссылаются), то нужно будет: удалять те объекты (вызывать DeleteOnSubmit(entity)), которые пытались добавить(InsertOnSubmit(entity)) у ModelDataContext , так же добавлять те объекты, которые пытались обновлять, ну и Refresh-ить объекты, которые хотели просто обновить. В общем странно, почему не сделали в DLinq стандартный Rollback метод, вроде все должно быть прозрачно.

Выбор пути, по которому вы будете использовать DLinq в вашем проекте, зависит только от вас и от вашего проекта. Если есть еще какие либо методы работы с Linq-To-Sql с удовольствием послушаю и приму к сведению.

Have a question? Want to follow up? Send a comment? Or just ask for help or consultation? Send me an email at public[at]denis[dot]gladkikh[one more dot]email.