NHibernate HasMany 关系。在会话重新打开之前,集合为空
我遇到了 NHibernate 的问题,而且我想,还有延迟加载的问题。
我有两个相互关联的实体类:
public class User
{
// lots of properties
public virtual Role Role { get; set; }
}
public class Role
{
// properties
public virtual IList<User> UsersInRole { get;set; }
public Role()
{
this.UsersInRole = new List<User>();
}
}
关系是一对多(一个角色 - 许多用户)。 类使用 Fluent 进行映射,如下所示:
public class UserMapping : ClassMap<Models.Accounts.User>
{
public UserMapping()
{
this.Table("Users");
this.Id(u => u.ID).GeneratedBy.Native();
//properties mapping
this.References<Models.Accounts.Role>(u => u.Role);
}
}
public class RoleMapping : ClassMap<Models.Accounts.Role>
{
public RoleMapping()
{
this.Table("Roles");
this.Id(r => r.ID).GeneratedBy.Native();
// properties mapping
this.HasMany<User>(r => r.Users).AsBag().Inverse().KeyColumn("Role_id");
}
}
当我创建角色并向其分配一些用户时 - Role::Users 属性为 null,直到会话关闭并打开另一个会话。因此,请考虑以下代码:
object Foo()
{
var session = FluentManager.OpenNewSession();
var t1 = session.BeginTransaction();
Role role = new Role("admin");
session.SaveOrUpdate(role);
t1.Commit();
var t2 = session.BeginTransaction();
session.SaveOrUpdate(new User() { Login = "log1", Role = role });
t2.Commit();
Role oldRole = session.Get<Role>((uint)1);
return oldRole.Users; // null here
}
另一方面,以下代码工作正常:
object Foo()
{
var session = FluentManager.OpenNewSession();
var t1 = session.BeginTransaction();
Role role = new Role("admin");
session.SaveOrUpdate(role);
t1.Commit();
var t2 = session.BeginTransaction();
session.SaveOrUpdate(new User() { Login = "log1", Role = role });
t2.Commit();
session.Close();
var session2 = FluentManager.OpenNewSession();
Role oldRole = session2.Get<Role>((uint)1);
return oldRole.Users; // Actual list of users
}
不过,我想在没有会话关闭的情况下使用给定角色中的用户集合。我做错了什么? 非常感谢。
PS:我正在使用 Fluent NHibernate 1.2 和 SQLite 数据库,如果这很重要的话。
I've got a problem with NHibernate and, as I suppose, with lazy load.
I've got two entity classes, that are related to each other:
public class User
{
// lots of properties
public virtual Role Role { get; set; }
}
public class Role
{
// properties
public virtual IList<User> UsersInRole { get;set; }
public Role()
{
this.UsersInRole = new List<User>();
}
}
Relation is One-To-Many (One role - Many users).
Classes are mapped with Fluent as following:
public class UserMapping : ClassMap<Models.Accounts.User>
{
public UserMapping()
{
this.Table("Users");
this.Id(u => u.ID).GeneratedBy.Native();
//properties mapping
this.References<Models.Accounts.Role>(u => u.Role);
}
}
public class RoleMapping : ClassMap<Models.Accounts.Role>
{
public RoleMapping()
{
this.Table("Roles");
this.Id(r => r.ID).GeneratedBy.Native();
// properties mapping
this.HasMany<User>(r => r.Users).AsBag().Inverse().KeyColumn("Role_id");
}
}
When I'm creating a Role, and assign some User to it - Role::Users property is null until session is closed and another one is opened. So, consider following code:
object Foo()
{
var session = FluentManager.OpenNewSession();
var t1 = session.BeginTransaction();
Role role = new Role("admin");
session.SaveOrUpdate(role);
t1.Commit();
var t2 = session.BeginTransaction();
session.SaveOrUpdate(new User() { Login = "log1", Role = role });
t2.Commit();
Role oldRole = session.Get<Role>((uint)1);
return oldRole.Users; // null here
}
On the other hand, following code works fine:
object Foo()
{
var session = FluentManager.OpenNewSession();
var t1 = session.BeginTransaction();
Role role = new Role("admin");
session.SaveOrUpdate(role);
t1.Commit();
var t2 = session.BeginTransaction();
session.SaveOrUpdate(new User() { Login = "log1", Role = role });
t2.Commit();
session.Close();
var session2 = FluentManager.OpenNewSession();
Role oldRole = session2.Get<Role>((uint)1);
return oldRole.Users; // Actual list of users
}
Though, I'd like to work with collection of users in a given role w/out session close. What I did wrong?
Many thanks in advance.
PS: I'm using Fluent NHibernate 1.2 with SQLite database, if that matters.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一个示例中 role.Users 为 null 的原因是因为您没有手动处理这种关系。您需要自己维护双向关系。在您的第一个示例中,它没有从数据库获取您的 Role 对象。它是从 Session 获取的。在第二个示例中,您关闭会话并打开一个新会话。这迫使它从数据库中读取信息,此时您的关系将完好无损。我可能会采取以下措施来纠正此问题:
您的示例现在看起来像这样:
您还可以查看以下内容以获取更多详细信息:
获取要加载的多对多关系
The reason why role.Users is null in the first example is because you don't manually take care of this relationship. You need to maintain the bidirectional relationship yourself. In your first example it is not getting your Role object from the database. It's getting it from Session. In your 2nd example you close your session and open a new one. This forces it to read the information from the database and your relationships will be intact at this point. Here is what I might do to correct this:
Your example would now look something like this:
You can also take a look at the following for more detail:
Getting ManyToMany relationship to load
一些黑暗中的镜头:
您是否尝试过访问
role.Users
而不是oldRole.Users
?您是否尝试过删除 Role 的构造函数?
您是否尝试过使用独立条件或
QueryOver
而不是Get
来获取角色?也许你找错了角色。Some shots in the dark:
Have you tried accessing
role.Users
instead ofoldRole.Users
?Have you tried removing the constructor of Role?
Have you tried getting the role using a detached criteria or
QueryOver
rather thanGet
? Maybe you're getting the wrong role.