我们正在使用 NHibernate、C# .NET 开发应用程序,并且我们遇到了一个关于映射的问题……情况如下:
首先,我将放置我们的映射文件:
这是 User.hbm.xml 映射:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="GLib.GSecurity.Domain" namespace="Geraes.GLib.GSecurity.Domain" >
<typedef class="uNhAddIns.UserTypes.EncryptedString, uNhAddIns" name="Encrypted">
<param name="encryptor">uNhAddIns.UserTypes.uNHAddinsEncryptor, uNhAddIns</param>
<param name="encryptionKey">myRGBKey</param>
</typedef>
<class name="User" table="S_User" lazy="false" dynamic-update="true">
<id name="Id" column="Id_User" type="Int64">
<generator class="Geraes.GLib.GDomainBasis.CustomTableHiLoGenerator, GLib.GDomainBasis" />
</id>
<many-to-one name="Plant" column="Id_Plant" class="Plant"
foreign-key="fk1_User" cascade="none" fetch="join" not-null="true"/>
<property name="Login" column="Login" type="String" length="16" not-null="true" />
<property name="Password" column="Password" type="Encrypted" />
<property name="Name" column="Name" type="String" length="64" not-null="true" />
<property name="Active" column="Active" type="Char" not-null="true" />
<idbag name="RightProfiles" table="S_User_Right_Profile" generic="true" lazy="false" cascade="save-update" fetch="join">
<collection-id type="Int64" column="Id_User_Right_Profile">
<generator class="Geraes.GLib.GDomainBasis.CustomTableHiLoGenerator, GLib.GDomainBasis" />
</collection-id>
<key column="Id_User" />
<many-to-many column="Id_Right_Profile" class="RightProfile" fetch="join"/>
</idbag>
</class>
</hibernate-mapping>
这是 RightProfile.hbm.xml 映射:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="GLib.GSecurity.Domain" namespace="Geraes.GLib.GSecurity.Domain" >
<class name="RightProfile" table="S_Right_Profile" lazy="false" dynamic-update="true">
<id name="Id" column="Id_Right_Profile" type="Int64">
<generator class="Geraes.GLib.GDomainBasis.CustomTableHiLoGenerator, GLib.GDomainBasis" />
</id>
<property name="Name" column="Name" type="String" length="20" not-null="true" />
<property name="Description" column="Description" type="String" length="60" not-null="true" />
<idbag name="Resources" table="S_Right_Profile_Resource" generic="true" lazy="false" cascade="save-update" fetch="join">
<collection-id type="Int64" column="Id_Right_Profile_Resource">
<generator class="Geraes.GLib.GDomainBasis.CustomTableHiLoGenerator, GLib.GDomainBasis" />
</collection-id>
<key column="Id_Right_Profile" />
<many-to-many column="Id_Resource" class="Resource" fetch="join"/>
</idbag>
<idbag name="Users" table="S_User_Right_Profile" generic="true" inverse="true" lazy="false" cascade="save-update" fetch="join">
<collection-id type="Int64" column="Id_User_Right_Profile">
<generator class="Geraes.GLib.GDomainBasis.CustomTableHiLoGenerator, GLib.GDomainBasis" />
</collection-id>
<key column="Id_Right_Profile" />
<many-to-many column="Id_User" class="User" fetch="join"/>
</idbag>
</class>
</hibernate-mapping>
现在,我们的实体类:
User.cs 实体类:
public class User : BaseEntityEditable
{
public virtual Plant Plant { get; set; }
public virtual String Login { get; set; }
public virtual String Password { get; set; }
public virtual String Name { get; set; }
public virtual Char Active { get; set; }
public virtual IList<RightProfile> RightProfiles { get; set; }
public override String ToString()
{
return Name + " - " + Login;
}
public User()
{
RightProfiles = new List<RightProfile>();
Plant = new Plant();
}
}
RightProfile.cs 实体类:
public class RightProfile : BaseEntityEditable
{
public virtual String Name { get; set; }
public virtual String Description { get; set; }
public virtual IList<Resource> Resources { get; set; }
public virtual IList<User> Users { get; set; }
public override String ToString()
{
return Name + " - " + Description;
}
public RightProfile()
{
Resources = new List<Resource>();
Users = new List<User>();
}
}
所以,我们的情况是:
我们正在开发一个窗口。在这个窗口中,我们有 2 个网格。用户网格和组网格。当这个窗口被加载时,我们的 viewModel start 会进行必要的查询来带来数据。第一个查询带来所有用户,在用户内部,我们有一个 RightProfile 列表,其中包含填充其他网格所需的所有数据。到目前为止,一切都很好。我们的问题是,nhibernate 开始进行查询,带来所有 RightProfiles 的所有用户。
他不能那样做!我们已经拥有了所有需要的数据!
-- 已编辑 --
我们的第一部分运行正常,我们搜索用户,搜索 RightProfiles(填充网格),然后,我们在该网格内标记允许的用户。事实上,我的窗户工作得很好。我们的问题是,在 Nhibernate Log 中,他正在为每个关联的具有关联的 Right Profile 的用户进行选择。
一旦数据已经加载,这些选择是不必要的。这是我的问题,nhibernate 正在做更多需要做的选择。
我怎么能改变这个?
-- 编辑 2: -- 这是 NHibernate Log 生成的 SQL:
这个选择没问题:
SELECT
this_.Id_Right_Profile as Id1_36_3_,
this_.Name as Name36_3_,
this_.Description as Descript3_36_3_,
resources2_.Id_Right_Profile as Id1_5_,
resource3_.Id_Resource as Id2_5_,
resources2_.Id_Right_Profile_Resource as Id3_5_,
resource3_.Id_Resource as Id1_39_0_,
resource3_.Name as Name39_0_,
users4_.Id_Right_Profile as Id1_6_,
user5_.Id_User as Id2_6_,
users4_.Id_User_Right_Profile as Id3_6_,
user5_.Id_User as Id1_42_1_,
user5_.Id_Plant as Id2_42_1_,
user5_.Login as Login42_1_,
user5_.Password as Password42_1_,
user5_.Name as Name42_1_,
user5_.Active as Active42_1_,
plant6_.Id_Plant as Id1_41_2_,
plant6_.Name as Name41_2_,
plant6_.Description as Descript3_41_2_
FROM
S_Right_Profile this_
left outer join
S_Right_Profile_Resource resources2_
on this_.Id_Right_Profile=resources2_.Id_Right_Profile
left outer join
S_Resource resource3_
on resources2_.Id_Resource=resource3_.Id_Resource
left outer join
S_User_Right_Profile users4_
on this_.Id_Right_Profile=users4_.Id_Right_Profile
left outer join
S_User user5_
on users4_.Id_User=user5_.Id_User
left outer join
S_Plant plant6_
on user5_.Id_Plant=plant6_.Id_Plant
ORDER BY
this_.Name asc
在我看来,这个选择是不必要的(它对每个用户重复):
SELECT
rightprofi0_.Id_User as Id2_1_,
rightprofi0_.Id_Right_Profile as Id1_1_,
rightprofi0_.Id_User_Right_Profile as Id3_1_,
rightprofi1_.Id_Right_Profile as Id1_36_0_,
rightprofi1_.Name as Name36_0_,
rightprofi1_.Description as Descript3_36_0_
FROM
S_User_Right_Profile rightprofi0_
left outer join
S_Right_Profile rightprofi1_
on rightprofi0_.Id_Right_Profile=rightprofi1_.Id_Right_Profile
WHERE
rightprofi0_.Id_User=:p0;
:p0 = 10807 [Type: Int64 (0)]