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つのグリッドがあります。ユーザー用のグリッド、およびグループ用のグリッド。このウィンドウが読み込まれると、viewModelstartはデータを取得するために必要なクエリを実行します。最初のクエリはすべてのユーザーを取得し、ユーザー内には、他のグリッドにデータを入力するために必要なすべてのデータを含むRightProfilesのリストがあります。ここまでは順調ですね。私たちの問題は、nhibernateがクエリを作成し始め、すべてのRightProfilesのすべてのユーザーを連れてくることです。
彼はそれをすることはできません!必要なデータはすべて揃っています。
-編集済み-
最初の部分は正常に実行されています。ユーザーを検索し、RightProfilesを検索して(グリッドにデータを入力するため)、次に、そのグリッド内でユーザーに許可されているものをマークします。実際、私のウィンドウは問題なく機能します。私たちの問題は、Nhibernate Log内で、関連付けられたRightProfileを持つ関連付けられたユーザーごとに選択を行っていることです。
データがすでにロードされている場合、これらの選択は不要です。これが私の問題です。nhibernateは実行する必要のある選択をはるかに多く行っています。
どうすればこれを変更できますか?
-編集2: -NHibernateログによって生成されたSQLは次のとおりです。
この選択はOKです:
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)]