Nhibernate:阻止它加入不需要的表

时间:2010-06-08 18:46:21

标签: nhibernate fluent-nhibernate nhibernate-mapping

我有两个与以下类相关的表(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表“WhereID = 1(任何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上过滤时不查询它?

3 个答案:

答案 0 :(得分:2)

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

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

我提出了两种解决方案。虽然使用CreateCriteria确实创建了正确的查询,但它与我实现访问层的方式无关。我仍然需要根据传入的Expressions<Func<T,bool>>语句执行语句。我找到的两种可能的解决方案是:

  1. 使用此库从lambda语句中创建条件。

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

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

  2. 最后,使用Linq和我的查询的最佳解决方案是下载并构建Nhibernate 3的开发版本.NH3中新的Linq提供程序运行良好,查询看起来正如我所料。

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

答案 1 :(得分:1)

什么是查询代码?这应该有用。

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

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

答案 2 :(得分:0)

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

例如,我有2个表:

客户 为了

1个客户有0个订单。

通过LINQ更新订单将更新附加客户。在我的实例中,它是在表中插入一个重复的客户。

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

伪代码:

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

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