如何优化 ICriteria 以在 NHIbernate 中进行选择?

发布于 2024-11-29 15:09:52 字数 2634 浏览 2 评论 0原文

首先,我确信一定有一个简单的解决方案,但我就是找不到。 (是的,我已经用谷歌搜索过)

如果我运行这个 Criteria..

IList<Team> teams = session.CreateCriteria<Team>("t")
.CreateCriteria("t.TeamMembers", "m")
.Add(Expression.Eq("m.Enabled", true))
.List<Team>();

..生成的 SQL 类似于:

SELECT t.*, m.* FROM Teams t INNER JOIN TeamMembers m ON t.ID = m.TeamID

因为我只需要表 Teams 中的列。如何指示 NHibernate 停止从 TeamMembers 获取未使用的列?

(我的实际实现非常复杂,会返回大量数据,因此为了简洁起见,这是一个简化的示例)

编辑:“添加: .Add(Expression.Eq("m. Enabled", true))" 到标准

这是我使用相同设置进行的测试:

类:

public class Team
    {
        public virtual int ID { get; private set; }
        public virtual Iesi.Collections.Generic.ISet<Member> Members { get; set; }
    }

    public class Member
    {
        public virtual int ID { get; private set; }
        public virtual bool Enabled { get; set; }
        public virtual Team Team { get; set; }
    }

映射:

<class xmlns="urn:nhibernate-mapping-2.2" name="TestApp.Team, ClassLib" table="`Team`">
    <id access="backfield" name="ID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="ID" />
      <generator class="identity" />
    </id>
    <set lazy="true" name="Members">
      <key>
        <column name="TeamID" />
      </key>
      <one-to-many class="TestApp.Member, ClassLib" />
    </set>
  </class>
  <class xmlns="urn:nhibernate-mapping-2.2" name="TestApp.Member, ClassLib" table="`Member`">
    <id access="backfield" name="ID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="ID" />
      <generator class="identity" />
    </id>
    <property name="Enabled" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Enabled" />
    </property>
    <many-to-one class="TestApp.Team, ClassLib" name="Team">
      <column name="TeamID" />
    </many-to-one>
  </class>

生成的 SQL:

 SELECT this_.ID as ID11_1_, m1_.ID as ID10_0_, m1_.Enabled as Enabled10_0_, m1_.TeamID as TeamID10_0_ FROM "Team" this_ inner join "Member" m1_ on this_.ID=m1_.TeamID WHERE m1_.Enabled = @p0;@p0 = True [Type: Boolean (0)]

澄清说明:我顺便命名了 TeamMembers到我的测试示例中的Members

First of all, I'm sure there must be a simple solution to this but I just can't find it. (Yes, I have googled it)

If I run this Criteria..

IList<Team> teams = session.CreateCriteria<Team>("t")
.CreateCriteria("t.TeamMembers", "m")
.Add(Expression.Eq("m.Enabled", true))
.List<Team>();

..the generated SQL is similar to:

SELECT t.*, m.* FROM Teams t INNER JOIN TeamMembers m ON t.ID = m.TeamID

Since I only need the columns from table Teams. How do I instruct NHibernate stop fetching the unused columns from TeamMembers?

(My real implementation is quite complex which returns lots of data so this is a simplified example for brevity)

EDIT: " Added: .Add(Expression.Eq("m.Enabled", true))" to the Criteria

Here's a test I made with the same setup:

Classes:

public class Team
    {
        public virtual int ID { get; private set; }
        public virtual Iesi.Collections.Generic.ISet<Member> Members { get; set; }
    }

    public class Member
    {
        public virtual int ID { get; private set; }
        public virtual bool Enabled { get; set; }
        public virtual Team Team { get; set; }
    }

Mappings:

<class xmlns="urn:nhibernate-mapping-2.2" name="TestApp.Team, ClassLib" table="`Team`">
    <id access="backfield" name="ID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="ID" />
      <generator class="identity" />
    </id>
    <set lazy="true" name="Members">
      <key>
        <column name="TeamID" />
      </key>
      <one-to-many class="TestApp.Member, ClassLib" />
    </set>
  </class>
  <class xmlns="urn:nhibernate-mapping-2.2" name="TestApp.Member, ClassLib" table="`Member`">
    <id access="backfield" name="ID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="ID" />
      <generator class="identity" />
    </id>
    <property name="Enabled" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Enabled" />
    </property>
    <many-to-one class="TestApp.Team, ClassLib" name="Team">
      <column name="TeamID" />
    </many-to-one>
  </class>

Generated SQL:

 SELECT this_.ID as ID11_1_, m1_.ID as ID10_0_, m1_.Enabled as Enabled10_0_, m1_.TeamID as TeamID10_0_ FROM "Team" this_ inner join "Member" m1_ on this_.ID=m1_.TeamID WHERE m1_.Enabled = @p0;@p0 = True [Type: Boolean (0)]

Note for clarification: I incidentally named the TeamMembers to Members in my test example.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

煞人兵器 2024-12-06 15:09:52

更新更新问题

可能最好在配置中使 Members 集合变得懒惰

<set name="Members" lazy="true">

,然后仅在需要时进行其他设置,例如

.SetFetchMode("TeamMembers", FetchMode.Eager) 

UPDATED FOR UPDATE QUESTION

It's probably best to make the Members collection lazy in the configuration

<set name="Members" lazy="true">

and then only set otherwise when required like

.SetFetchMode("TeamMembers", FetchMode.Eager) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文