【问题标题】:Execute IQueryable on DB Layer and return a new One (eraly execute)在 DB 层上执行 IQueryable 并返回一个新的 (eraly 执行)
【发布时间】:2013-02-03 18:54:40
【问题描述】:

我想我的 DB 层返回一个 IQueryable 的 DTO 对象。我使用 NHibernate,它支持 Linq。但问题是,当我的数据库层离开时,我必须关闭会话,因此 IQueryable 不再工作。 但我也无法返回列表,因为这样查询将不会在 SQL Server 上执行。

那么我是否有可能返回一个 IQueryable,使用 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?

【问题讨论】:

  • 你想达到什么目的?
  • 我希望表达式进入我的数据层,并在服务器上执行。但是我希望在枚举 IQueryable 时立即执行而不是首先执行。但我不能从我的数据层返回一个列表,因为那时表达式没有转到服务器。而且我也不能使用来自 Linq 的 IQueryable,因为在枚举完成之前我无法处理会话!
  • 要执行的表达式在哪里?属性没有参数来传递表达式。返回IQueryable后,连接丢失,无用
  • 是的,我知道属性没有参数。但是使用原始的 IQueryable,它也适用于获取表达式树。我认为 IQuerable 的工作方式有点像回调,返回对象然后使用表达式树?还是我错了。

标签: linq nhibernate iqueryable


【解决方案1】:

提前执行与返回列表相同。如果没有与数据库(会话)的连接,您怎么可能对其执行查询?不要像这样对会话进行微观管理,而是在整个业务操作中使用/保持会话,并且关闭的事务不再有问题。

从 DAL 返回 IQueryable 会比您想象的更快导致痛苦,因为数据访问绝对没有上下文来优化访问(渴望获取、过滤、用于多次迭代的 ToList())。如果没有上下文,一致的缓存也几乎是不可能的。

【讨论】:

  • 我有一个到数据库的连接,但只在数据层中。这意味着,当 getter 离开时,会话对象应该被释放!
  • @JochenKühner 这通常是问题所在......让数据层定义会话和事务边界通常是错误的做法。例如,请参阅“视图中的打开会话”或“每个请求的会话”模式。
  • 也许那是错误的,但我无法更改整个应用程序!我只想知道,我的问题有解决方案吗?
  • 除了返回一个 List 之外,您还可以实现自己的 IQueryable Provider 来序列化和反序列化整个查询。这将是一个巨大的项目,具体取决于所涉及查询的复杂性。您几乎肯定会遇到 SELECT N+1 和缓存问题。错误处理(r.g. databaseexceptions) 将在整个业务逻辑中的每个.ToList()/.ToArray() 调用中受到影响
  • 也许这对我有帮助:interlinq.codeplex.com 它支持 Linq over WCF,为此查询已经必须序列化?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-15
  • 2020-12-08
  • 1970-01-01
  • 1970-01-01
  • 2016-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多