IQueryable + DataContext
От: e.thrash  
Дата: 21.10.15 06:16
Оценка:
Есть класс MyRepository
В нем есть куча разных методов которые возвращают IQueryable и в разных методах могут использоваться разные контексты.
Задача делать Dispose контекста. Вся соль что в разных методах могут быть разные контексты.
Как не по корявому освобождать контекст?
ДУмал завести переменную в классе Репозитория и реализовать IDisposable в репозитории, но данный кейс не работает, если вдруг я вызову 2 метода с разными контекстами.
Вот думаю если завести массив контекстов и в Dispose их освобождать. Кто что думает?
Re: IQueryable + DataContext
От: Doc Россия http://andrey.moveax.ru
Дата: 21.10.15 06:21
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET> Кто что думает?


Возвращать IEnumerable и не отпускать контекст дальше repository?
Re[2]: IQueryable + DataContext
От: e.thrash  
Дата: 21.10.15 08:33
Оценка:
Здравствуйте, Doc, Вы писали:

Doc>Здравствуйте, e.thrash, Вы писали:


ET>> Кто что думает?


Doc>Возвращать IEnumerable и не отпускать контекст дальше repository?


внутри репозитория много внутренних методов, которые возвращают данные из больших таблиц, а потом уже вызвавшие методы делают разные группировки для своих нужд.
получается делать кучу отдельных методов?
Re[3]: IQueryable + DataContext
От: Doc Россия http://andrey.moveax.ru
Дата: 21.10.15 08:42
Оценка: 5 (2)
Здравствуйте, e.thrash, Вы писали:

ET>внутри репозитория много внутренних методов, которые возвращают данные из больших таблиц, а потом уже вызвавшие методы делают разные группировки для своих нужд.

ET>получается делать кучу отдельных методов?

Можно воспользоваться шаблонами Specification или CQRS
Или методы репозитария принимают параметры для сортировки и группировки (там где это разумно и возможно).

Но идея одна — или вы считаете что контекст это уже DAL и просто можете использовать его напрямую из кода (есть и такой подход) или же контекст не выходит за рамки содержащей его реализации шаблона.

Не исключаю что это потребует много рефакторнига, но тут уже смотрите что лучше для вас.
Re: IQueryable + DataContext
От: Sharov Россия  
Дата: 21.10.15 10:36
Оценка:
Здравствуйте, e.thrash, Вы писали:


ET>Вот думаю если завести массив контекстов и в Dispose их освобождать. Кто что думает?


А нельзя освобождать контекст сразу в методе?
Кодом людям нужно помогать!
Re[2]: IQueryable + DataContext
От: Doc Россия http://andrey.moveax.ru
Дата: 21.10.15 11:15
Оценка: 9 (2) +2
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, e.thrash, Вы писали:



ET>>Вот думаю если завести массив контекстов и в Dispose их освобождать. Кто что думает?

S>А нельзя освобождать контекст сразу в методе?

IQueryable это отложенное выполнение самого запроса. Т.е. контекст должен жить до этого момента, а он за пределами метода. Именно поэтому возврат IQueryable дело очень рисковое.
Re[3]: IQueryable + DataContext
От: Sharov Россия  
Дата: 21.10.15 11:23
Оценка:
Здравствуйте, Doc, Вы писали:


Doc>IQueryable это отложенное выполнение самого запроса. Т.е. контекст должен жить до этого момента, а он за пределами метода. Именно поэтому возврат IQueryable дело очень рисковое.


Ога, понял теперь суть вопроса. Таки да, возвращать IQueryable не самая лучшая идея... Лучше возвращать конкретные данные.
Кодом людям нужно помогать!
Re: IQueryable + DataContext
От: Sinix  
Дата: 21.10.15 12:24
Оценка: 1 (1) +1
Здравствуйте, e.thrash, Вы писали:

ET>Вот думаю если завести массив контекстов и в Dispose их освобождать. Кто что думает?


1. Если используются poco + change tracking, то "время жизни объекта > времени жизни контекста" — не самая лучшая идея
c Self-Tracking Entity, насколько помню, проблем не возникало.

2. Подтягивание всех данных может _очень_ больно выстрелить, если данных много. В ранних версиях это компенсировалось тем, что сами авторы EF с Dispose не сильно заморачивались и можно было баз особой дисциплины разбрасываться IQueryable. Не самая лучшая идея, конечно, но оно хотя бы не создавало проблем. Начиная с EF6 поведение поменялось: вручную открытое соединение не закрывается вплоть до диспоза контекста. Сюрпрайз, блин.

3. Итого, из всех велосипедов чаще всего оставляют вот этот: http://mehdi.me/ambient-dbcontext-in-ef6/
Re: IQueryable + DataContext
От: Vladek Россия Github
Дата: 21.10.15 22:47
Оценка: +1
Здравствуйте, e.thrash, Вы писали:

ET>Есть класс MyRepository

ET>В нем есть куча разных методов которые возвращают IQueryable
Выстрел в ногу.
ET>Задача делать Dispose контекста. Вся соль что в разных методах могут быть разные контексты.
Наступил простреленной ногой на грабли.

ET>Как не по корявому освобождать контекст?

ET>ДУмал завести переменную в классе Репозитория и реализовать IDisposable в репозитории, но данный кейс не работает, если вдруг я вызову 2 метода с разными контекстами.
ET>Вот думаю если завести массив контекстов и в Dispose их освобождать. Кто что думает?

Репозиторий, по определению, представляет собой коллекцию объектов из предметной области приложения. Это точно не классы, обслуживаемые EF. Это полноценные объекты, обладающие не только состоянием, но и поведением, имеющим смысл в рамках предметной области. То есть, не надо навязывать классы EF другим компонентам приложения, они не должны от них зависеть или вообще знать о них. Поэтому, если репозиторий возвращает полноценные объекты, не имеющие отношения к контекстам EF, проблема вообще не возникает.

Ну ладно, это было бы здорово, но, допустим, у нас нет никакой модели предметной области, вместо этого мы используем объекты-данные из контекстов EF, а логика предметной области у нас располагается в процедурах, которые мы ловко замаскировали под классы с методами, но почти без полей. Репозиторий извлекает данные — это его задача. Управление временем жизни контекстов EF — это другая задача, навесив которую на репозиторий, мы слишком усложним его. Будет удобно отдать эту задачу другому объекту — какой-нибудь фабрике. Пусть фабрика возвращает обёртки с контекстами в каждом методе репозитория, а репозиторий их уничтожает после использования. Обёртки сами сообразят, что делать с контекстом в момент уничтожения.

Но, мне кажется, EF последних версий достаточно умён, чтобы контексты можно было создавать и уничтожать сколько угодно раз. Внутри у него кэш дожен быть. Это упростит нашу фабрику, которая будет создавать новый контекст на каждый запрос без всяких обёрток, а вызывающий метод спокойно его уничтожать после использования. Остаётся проблема с возвращением IQueryable — грубо говоря, репозиторий вместо данных возвращает собственные кишки, набитые экскрементами и данными. Надо всё-таки собрать кишки обратно в репозиторий и возвращать конкретные данные, свободные от контекста (return data.ToArray(). Это сделать достаточно просто: весь код, преобразующий IQueryable, полученные от репозитория, должен принадлежать репозиторию.
http://files.rsdn.org/43395/hr-kyle-theisen-04.png
Re[2]: IQueryable + DataContext
От: __SPIRIT__ Россия  
Дата: 24.10.15 15:03
Оценка: -1
Здравствуйте, Vladek, Вы писали:

ET>>Есть класс MyRepository

ET>>В нем есть куча разных методов которые возвращают IQueryable
V>Выстрел в ногу.

в чем собственно проблема?

З.Ы.
Читая все скипнутое перестаешь удивляться популярности node.js...
Re[3]: IQueryable + DataContext
От: Vladek Россия Github
Дата: 24.10.15 16:57
Оценка: +2
Здравствуйте, __SPIRIT__, Вы писали:

__S>в чем собственно проблема?


В утере контроля над этими объектами. Теперь они могут меняться где-угодно и из этого вытекают все другие проблемы.

__S>Читая все скипнутое перестаешь удивляться популярности node.js...


Описанное не имеет отношения к конкретным технологиям, это вопрос контроля и направления зависимостей между объектами в ООП.
http://files.rsdn.org/43395/hr-kyle-theisen-04.png
Re[4]: IQueryable + DataContext
От: __SPIRIT__ Россия  
Дата: 24.10.15 19:48
Оценка:
Здравствуйте, Vladek, Вы писали:

__S>>в чем собственно проблема?

V>В утере контроля над этими объектами. Теперь они могут меняться где-угодно и из этого вытекают все другие проблемы.

дык я и спрашивал про проблемы. Насколько я понимаю речь про десктоп? Потому что для web вообще проблем не видно...

__S>>Читая все скипнутое перестаешь удивляться популярности node.js...

V>Описанное не имеет отношения к конкретным технологиям, это вопрос контроля и направления зависимостей между объектами в ООП.

описанное увеличивает сроки и стоимость проекта а вот плюсов от него нет совсем. Любое большое изменение и слой абстракции не поможет а только усугубит проблему...
Re[5]: IQueryable + DataContext
От: Vladek Россия Github
Дата: 25.10.15 10:05
Оценка:
Здравствуйте, __SPIRIT__, Вы писали:

__S>дык я и спрашивал про проблемы. Насколько я понимаю речь про десктоп? Потому что для web вообще проблем не видно...


__S>описанное увеличивает сроки и стоимость проекта а вот плюсов от него нет совсем. Любое большое изменение и слой абстракции не поможет а только усугубит проблему...


Приятного просмотра.

http://www.youtube.com/watch?v=HhNIttd87xs
http://files.rsdn.org/43395/hr-kyle-theisen-04.png
Re[6]: IQueryable + DataContext
От: __SPIRIT__ Россия  
Дата: 25.10.15 16:17
Оценка:
Здравствуйте, Vladek, Вы писали:

__S>>дык я и спрашивал про проблемы. Насколько я понимаю речь про десктоп? Потому что для web вообще проблем не видно...


__S>>описанное увеличивает сроки и стоимость проекта а вот плюсов от него нет совсем. Любое большое изменение и слой абстракции не поможет а только усугубит проблему...


V>Приятного просмотра.


Очевидно что самый быстрый вариант ответа на вопрос "в чем проблема вернуть кверибл?" это дать ссылку без лишних слов и идей на полуторачасовое видео...

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


Upd.
Где в видео хоть что-то интересное? Много слов а толк где?
Отредактировано 25.10.2015 18:33 __SPIRIT__ . Предыдущая версия .
Re: IQueryable + DataContext
От: Слава  
Дата: 25.10.15 17:24
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>Есть класс MyRepository

ET>В нем есть куча разных методов которые возвращают IQueryable и в разных методах могут использоваться разные контексты.

Отказаться от понятия "репозиторий" вообще. Как тут советуют создатели linq2db.
Re[2]: IQueryable + DataContext
От: TK Лес кывт.рф
Дата: 26.10.15 06:27
Оценка:
Здравствуйте, Doc, Вы писали:

ET>> Кто что думает?

Doc>Возвращать IEnumerable и не отпускать контекст дальше repository?

Ничем принципиальным не отличается от IQueryable. IQueryable это просто интерфейс и с DataContext он связан опосредованно.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re: IQueryable + DataContext
От: TK Лес кывт.рф
Дата: 26.10.15 06:37
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>Есть класс MyRepository

ET>В нем есть куча разных методов которые возвращают IQueryable и в разных методах могут использоваться разные контексты.
ET>Задача делать Dispose контекста. Вся соль что в разных методах могут быть разные контексты.
ET>Как не по корявому освобождать контекст?
ET>ДУмал завести переменную в классе Репозитория и реализовать IDisposable в репозитории, но данный кейс не работает, если вдруг я вызову 2 метода с разными контекстами.
ET>Вот думаю если завести массив контекстов и в Dispose их освобождать. Кто что думает?

IQueryable это есть простейший построитель запросов с отложенным выполнением. При этом, никто не заставляет вас использовать это самое "выполнение".
Можно использовать только ту часть, что отвечает за построение запроса, а выполнение перенести в MyRespository:

public static class DataSources
{
    public IQueryable<TData> Data => Enumerable.Empty<TData>().AsQueryable();
}

public static class DataRepository
{
    public IEnumerable<TData> Execute<TData>(IQueryable<TData> source)
    {
        // смотрим здесь в source.Expression, проверяем условия и на основе его формируем финальный запрос.
    }
}
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[5]: IQueryable + DataContext
От: Doc Россия http://andrey.moveax.ru
Дата: 26.10.15 08:01
Оценка:
Здравствуйте, __SPIRIT__, Вы писали:

__S>Потому что для web вообще проблем не видно...


С чего это? Например закрыть контекст до извлечения ответа очень легко (закрыть в контроллере, а полезть во view к данным)
Re[3]: IQueryable + DataContext
От: Doc Россия http://andrey.moveax.ru
Дата: 26.10.15 08:02
Оценка:
Здравствуйте, TK, Вы писали:

Doc>>Возвращать IEnumerable и не отпускать контекст дальше repository?

TK>Ничем принципиальным не отличается от IQueryable. IQueryable это просто интерфейс и с DataContext он связан опосредованно.

Т.е. нет необходимости поддерживать живым контекст до окончания работы IQueryable?
Re[6]: IQueryable + DataContext
От: __SPIRIT__ Россия  
Дата: 26.10.15 10:20
Оценка:
Здравствуйте, Doc, Вы писали:

__S>>Потому что для web вообще проблем не видно...


Doc>С чего это? Например закрыть контекст до извлечения ответа очень легко (закрыть в контроллере, а полезть во view к данным)


Во View кверибл не место 100%, тут даже спорить не о чем Но вот почему народ считает что нельзя вернуть кверибл из репозитория и как в таком случае избежать адского колличества специализированных методов(типа проставь флаг всем ордерам за последний месяц) абсолютно не понятно.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.