我目前正在編寫一個訪問遺留數據庫的應用程序。 我使用nhibernate作爲我的ORM。NHibernate CompositeId =>太多查詢
DB中有三個表格表示(幾乎)經典的多對多關係。 由於鏈接表還包含額外數據的視覺差異。
的代碼看起來是這樣的:
public class User
{
public virtual string Login { get; set;}
public virtual string Name { get; set;}
public virtual IList<UserRole> UserRoles { get; set;}
}
public class Role
{
public virtual int Id { get; set;}
public virtual string Description { get; set;}
public virtual IList<UserRole> UserRoles { get; set;}
}
public class UserRole
{
public virtual User User { get; set;}
public virtual Role Role { get; set;}
public virtual bool Active { get; set;}
}
public class UserMap : ClassMap<User>
{
public UserMap()
{
Table("Users");
Id(u => u.Login).Column("USER_LOGIN").GeneratedBy.Assigned();
Map(u => u.Name).Column("USER_NAME");
HasMany(u => u.UserRoles).KeyColumn("USER_LOGIN");
}
}
public class RoleMap : ClassMap<Role>
{
public RoleMap()
{
Table("Roles");
Id(r => r.Id).Column("ROLE_ID").GeneratedBy.Assigned();
Map(r => r.Description).Column("ROLE_DESCR");
HasMany(r => r.UserRoles).KeyColumn("ROLE_ID");
}
}
public class UserRoleMap : ClassMap<UserRole>
{
public UserRoleMap()
{
Table("UserRoles");
CompositeId()
.KeyReference(x => x.User, "USER_LOGIN")
.KeyReference(x => x.Role, "ROLE_ID");
Map(x => x.Active).Column("ROLE_IS_ACTIVE");
}
}
因此用戶可以有多個角色和角色有多個用戶。如我所說,經典的多對多。 但是,UserRoles表中還包含一個「活動」字段,我的應用程序 需要正確操作。
一切工作正常,但恕我直言nhibernate生成方式太多的查詢。 當我選擇一個用戶和訪問它的角色,這些都是在NHibernate的探查顯示 查詢:
SELECT user0_.USER_LOGIN as USER_LOGIN0_0_,
user0_.USER_NAME as USER_NAME_0_
FROM Users user0_
WHERE user0_.USER_ID = 'testuser'
-- Fetch the user
SELECT userrole0_.USER_LOGIN as USER_LOGIN1_,
userrole0_.ROLE_ID as ROLE_ID1_,
userrole0_.ROLE_ID as ROLE_ID1_0_,
userrole0_.USER_LOGIN as USER_LOGIN1_0_,
userrole0_.ROLE_IS_ACTIVE as ROLE_IS_ACTIVE1_0_
FROM UserRoles userrole0_
WHERE userrole0_.USER_LOGIN = 'testuser'
-- Fetch the roles for that user (why are some fields selected twice?)
-- returns three rows: roleids: 1, 2 and 3
SELECT userrole0_.ROLE_ID as ROLE_ID1_0_,
userrole0_.USER_LOGIN as USER_LOGIN1_0_,
userrole0_.ROLE_IS_ACTIVE as ROLE_IS_ACTIVE1_0_
FROM UserRoles userrole0_
WHERE userrole0_.USER_LOGIN = 'testuser'
and userrole0_.ROLE_ID = 1
SELECT userrole0_.ROLE_ID as ROLE_ID1_0_,
userrole0_.USER_LOGIN as USER_LOGIN1_0_,
userrole0_.ROLE_IS_ACTIVE as ROLE_IS_ACTIVE1_0_
FROM UserRoles userrole0_
WHERE userrole0_.USER_LOGIN = 'testuser'
and userrole0_.ROLE_ID = 2
SELECT userrole0_.ROLE_ID as ROLE_ID1_0_,
userrole0_.USER_LOGIN as USER_LOGIN1_0_,
userrole0_.ROLE_IS_ACTIVE as ROLE_IS_ACTIVE1_0_
FROM UserRoles userrole0_
WHERE userrole0_.USER_LOGIN = 'testuser'
and userrole0_.ROLE_ID = 3
-- Fetch all rows again separately but with full key?!?!!?
因此,NHibernate的開始與獲取我的用戶:OK 接下來,獲取角色爲該用戶:OK 但是,然後,第二個查詢返回的每一行都會再次從DB中檢索 ! 我不知道爲什麼會發生這種情況,因爲從第二個 查詢返回的數據實際上包含足夠的數據讓NHibernate填充我的整個UserRole對象。
是否有任何人誰可以:
- 向我解釋,爲什麼出現這種情況
- 幫我找出如何防止 這一點。即我想告訴NHibernate,UserRoles表上額外的 查詢是 不是必需的。
非常感謝! 問候, LDX
嗨,我試過這個,但他們不改變我得到的查詢量,只是他們執行的時間。在我第一次訪問Users.UserRoles列表時執行查詢之前。現在,當我查詢用戶對象時,查詢得到執行 – ldx 2011-04-07 15:15:45
@Idx:very strage ... Not.LazyLoad()方法用於提取具有唯一查詢的所有數據。我在某個查詢中使用了它,它完美地工作。我不明白毫無意義......無論如何,如果你想只有一個查詢,你不使用LazyLoad。祝你好運。 – Faber 2011-04-07 15:24:30