Выполнить IQueryable на уровне БД и вернуть новый (стереть выполнить)

Я знаю, что мой уровень БД возвращает IQueryable своих объектов DTO. Я использую NHibernate, который поддерживает Linq. Но проблема в том, что я должен закрыть сеанс, когда мой уровень БД покидает, и поэтому IQueryable больше не работает. Но я также не мог вернуть список, потому что тогда запросы не будут выполняться на SQL Server.

Возможно ли, что я верну IQueryable, исключу Expression с помощью Nhibernate LINQ и верну новый IQueryable?

может быть что-то вроде этого:

public IQueryable<TagDTO> Tags
    {
        get
        {
            using (var session = factory.OpenSession())
            {
                return new ExceuteQueryable<TagDTO>(session.Query<TagDTO>());
                //return session.Query<TagDTO>();
            }
        }
    }

где ExceuteQueryable должен использовать свое дерево выражений для выполнения запроса, получения списка результатов и возврата нового iqueryable списка?


person Jochen Kühner    schedule 19.02.2013    source источник
comment
чего ты пытаешься достичь?   -  person Firo    schedule 19.02.2013
comment
Я хочу, чтобы выражение приходило на мой уровень данных и выполнялось на сервере. Но я хочу, чтобы это выполнялось сразу, а не сначала при перечислении IQueryable. Но я не могу вернуть список из моего уровня данных, потому что тогда выражение не отправилось на сервер. И я также не могу использовать IQueryable ‹T› от Linq, потому что я не могу удалить сеанс до завершения перечисления!   -  person Jochen Kühner    schedule 19.02.2013
comment
где выполнить выражение? У свойств нет параметров, которые можно передать выражению. После возврата IQueryable соединение теряется и становится бесполезным.   -  person Firo    schedule 19.02.2013
comment
Да, я знаю, что у свойств нет параметров. Но с исходным IQueryable также работает Get the Expression Tree. Я думаю, что IQuerable работает как обратный вызов, где объект возвращается, а затем используется дерево выражений? Или я ошибаюсь.   -  person Jochen Kühner    schedule 19.02.2013


Ответы (1)


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

Возврат IQueryable из DAL приведет к боли раньше, чем вы думаете, потому что доступ к данным абсолютно не имеет контекста для оптимизации доступа (активная выборка, фильтрация, ToList () для многократных итераций). Кроме того, согласованное кэширование практически невозможно без контекста.

person Firo    schedule 19.02.2013
comment
У меня есть подключение к базе данных, но только в Datalayer. Это означает, что при выходе из геттера объект сеанса должен быть удален! - person Jochen Kühner; 19.02.2013
comment
@ JochenKühner И это часто проблема ... Очень часто неправильно позволять слою данных определять границы сеанса и транзакции. См., Например, открытую сессию в представлении или шаблоны сессий для каждого запроса. - person Oskar Berggren; 19.02.2013
comment
Возможно, это неправильно, но я не мог изменить все приложение! Я только хотел знать, есть ли решение моей проблемы? - person Jochen Kühner; 19.02.2013
comment
помимо возврата списка вы можете реализовать свой собственный поставщик IQueryable, который сериализует и десериализует весь запрос. Это будет огромный проект, в зависимости от сложности задействованных запросов. Вы почти наверняка столкнетесь с проблемами SELECT N + 1 и кешированием. Обработка ошибок (например, databaseexceptions) будет обрабатываться по каждому вызову _1 _ / _ 2_ в вашей бизнес-логике. - person Firo; 19.02.2013
comment
Может быть, это может мне помочь: interlinq.codeplex.com Он поддерживает Linq поверх WCF, и для этого уже есть Querys должны быть сериализованы? - person Jochen Kühner; 19.02.2013