【问题标题】:Nhibernate: Stop it from joining to a table that is not neededNhibernate:阻止它加入不需要的表
【发布时间】:2011-03-01 07:51:27
【问题描述】:

我有两个与以下类相关的表(tbArea、tbPost)。

class Area
{
    int ID
    string Name
    ...
}

class Post
{
    int ID
    string Title
    Area Area
    ...
}

这两个类映射到 Fluent Nhibernate。下面是贴图。

public class PostMapping : ClassMap<Post>
{
    public PostMapping()
    {
        Cache.NonStrictReadWrite();

        this.Table("tbPost");

        Id(x => x.ID)
            .Column("PostID")
            .GeneratedBy
            .Identity();

        References(x => x.Area)
            .ForeignKey("AreaID")
            .Column("AreaID");
        ...
    }
}

每当我对 Post 表“where AreaID = 1(any AreaId)”执行查询时,nhibernate 都会加入 area 表。

(Nhibernate 为查询生成的内容)

SELECT
    post fields
,   area fields (automatically added)
FROM tbPost p
LEFT JOIN tbArea a on 
        p.areaid = a.areaid
where
    p.areaid = 1

我已尝试将 Area 设置为 LazyLoad、Fetch.Select、ReadOnly 以及引用上的任何其他设置,但它仍将始终加入 Area。

我正在尝试优化后端数据库查询,并且由于我不需要加载刚刚过滤的区域对象,因此我想在每次查询发布时消除对区域的不必要连接。

我需要更改哪些配置或映射以使区域仍然与我的对象中的帖子相关,但在我过滤 AreaID 时不查询它?

【问题讨论】:

标签: nhibernate fluent-nhibernate nhibernate-mapping


【解决方案1】:

继续搜索后,我发现问题在于 Nhibernate Linq 库而不是我的映射或查询。我想我无法在这个问题上找到更多信息的原因是因为大多数使用 ORM 的人不会查看生成的查询。无论如何,这是确认我的问题的链接。

http://codeofrob.com/archive/2009/10/22/why-linq2nhibernate-isnt-ready-for-production-use.aspx

我想出了两个解决方案。虽然使用 CreateCriteria 实际上确实创建了正确的查询,但它不适用于我实现访问层的方式。我仍然需要根据传入的Expressions&lt;Func&lt;T,bool&gt;&gt; 语句执行 where 语句。我找到的两种可能的解决方案是:

  1. 使用这个库从 lambda 语句中创建标准。

    http://code.google.com/p/nhlambdaextensions/

    lambda 扩展的功能不如我希望的那样好,但可能适用于其他有同样问题的人。

  2. 最后,在我的查询中使用 Linq 的最佳解决方案是下载并构建 Nhibernate 3 的开发版本。NH3 中的新 Linq 提供程序完美运行,查询看起来与我预期的一样。

    http://sourceforge.net/projects/nhibernate/develop

【讨论】:

    【解决方案2】:

    查询代码是什么?这应该可以。

    s.CreateCriteria<Post>()
        .Add(Restrictions.Eq("Area.ID", 1))
        .List<Post>();
    

    使用多对一的 id 属性时不需要创建别名。因为,该值已经在 Post 表中。如果您尝试在任何其他 Area 属性上执行此操作,则需要 CreateAlias()。

    【讨论】:

    • 我必须使用 session.Query().Where(x => x.ID == ID)。原因是我有一个通过 Expresssion> 允许过滤的中间接口。有没有办法使用 createcriteria 执行 Expression linq where 语句,或者通过 Query() 执行此操作?
    【解决方案3】:

    不熟悉 NHibernate,但据我所知它类似于 LINQ。

    例如,我有 2 个表:

    客户 订购

    1 个客户有 0 个订单。

    通过 LINQ 更新订单将更新关联的客户。在我的例子中,它在表中插入了一个重复的客户。

    我必须在订单类中实现Detach() 方法。

    伪代码:

    public void Detach()
    {
       this._ReferenceToCustomer = emptyCustomerReference;
    }
    

    想法是将客户从订单中分离出来。这就是你所追求的吗?

    【讨论】:

      猜你喜欢
      • 2017-12-16
      • 1970-01-01
      • 2023-03-16
      • 2010-11-29
      • 1970-01-01
      • 2019-09-27
      • 2017-08-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多