与 NHIbernate 的多对多关系的 XML 映射文件
我有一个表 User,字段:Id,Username
我有一个表 UserGroup,字段:Id,UsergroupName,Code
我想按用户分配多个用户组,这意味着,我必须有第三个表:UserId 和 UsergroupId,这些表名为 UsersGroups
我尝试了以下代码:
用户表,XML:
<bag name="UsersGroups" generic="true" cascade="all" inverse="false" table="UsersGroups" >
<key column="UserId" />
<many-to-many column="GroupId" class="LookupUserGroup" />
</bag>
用户表,C#:
public virtual IList<UserGroup> UsersGroups { get; set; }
组表,C#(XML 映射中没有任何内容):
public virtual User User { get; set; }
要将组添加到用户,我在 User 类中使用 AddGroup,我这样做:
public virtual void AddGroup(UserGroup userGroup)
{
userGroup.User = this;
UsersGroups.Add(userGroup);
}
当我对 User 进行查询时,我想使用 linq 对“Code”字段进行一些检查,如下所示:
var res = (from c in MyUserList where c.UserGroup.Code == 1 select c );
但 Usergroup 字段在智能感知中不可用。
有什么想法吗?
谢谢,
I have a table User, fields : Id, Username
I have a table UserGroup, fields : Id, UsergroupName, Code
I'd like assign several Usergroup by user, that's mean, I have to have a third table with : UserId and UsergroupId, these table is named UsersGroups
I tried this code :
User table, XML :
<bag name="UsersGroups" generic="true" cascade="all" inverse="false" table="UsersGroups" >
<key column="UserId" />
<many-to-many column="GroupId" class="LookupUserGroup" />
</bag>
User table, C# :
public virtual IList<UserGroup> UsersGroups { get; set; }
Group table, C# (nothing in XML mapping):
public virtual User User { get; set; }
To add a group to a User, I use AddGroup in the User class, I do this :
public virtual void AddGroup(UserGroup userGroup)
{
userGroup.User = this;
UsersGroups.Add(userGroup);
}
When I make a query on User, I'd like use linq to make some check on the "Code" field like this :
var res = (from c in MyUserList where c.UserGroup.Code == 1 select c);
but USergroup field are not available in the intellisense.
Any idea ?
Thanks,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,您的 C# 类的设计似乎是错误的。它们并不反映您建立多对多关系的意图,而是反映一对多关系。由于每个组只允许一个用户通常没有意义,因此您应该将
UserGroup
类更改为并更改映射:
LookupUserGroup
类正确吗?在这个多对多关系的简单情况下,您应该只为三个表使用两个类。如果您有一个User
类和一个UserGroup
类,请删除LookupUserGroup
类并将其替换为User 中的映射.hbm.xml
。User 类中的 AddGroup 方法看起来有点像这样:
intellisense 不提供 UserGroup 字段的原因很简单,因为您没有这样的字段。该字段称为 UsersGroups(应该是 UserGroups),是一个
IList
。不幸的是,NHibernate 3.0 中当前的 Linq 提供程序并不真正支持您在此处尝试执行的查询类型。相反,您可以尝试使用 QueryOver。在你的情况下,它看起来像这样(改编自NHibernate QueryOver with ManytoMany)
我没有实现或测试任何这些,所以可能会有小错误。
First, the design of your C# classes seems to be wrong. They do not reflect your intention of having a many-to-many relationship, but a one-to-many relationship. Since it usually does not make sense to allow only one user per group, you should change the
UserGroup
class toand also change the mapping:
Is the
LookupUserGroup
class correct? You should only have two classes for three tables in this simple case of a many-to-many relationship. If you have aUser
class and aUserGroup
class, get rid of theLookupUserGroup
class and replace that in the mapping in theUser.hbm.xml
.The AddGroup method in your User class would then look a little like this:
The reason intellisense does not offer a UserGroup field is simply that you do not have such a field. The field is called UsersGroups (should be UserGroups) and is an
IList<UserGroup>
.Unfortunately the current Linq provider in NHibernate 3.0 does not really support the kind of query you are trying to do here. Instead, you can try using QueryOver. In your case it would look like this (adapted from NHibernate QueryOver with ManytoMany)
I did not implement or test any of this, so there may be minor errors.
克里斯,关于您的设计决策的简短说明。如果您确实想要拥有真正的多对多关系,那么您不需要第三个实体(UserGroup)。您只需要用户和组实体。 Nhibernate 将自行处理中间表的创建。但是,我从不使用这种方法。我更喜欢您所采取的方法(使用用户组实体),因为它为您提供了额外的灵活性。您永远不知道何时需要在用户和组之间的关系中获得其他信息(用户被添加到组的日期、谁创建了此关系等),因此我会使用 UsersGroups 实体,但是创建关系的方式是用户和用户组之间的多对一,以及组和用户组之间的多对一。通过这种方式,您可以通过额外的灵活性获得您想要的东西。
Kris, a short note about your design decision. If you really want to have a real many-to-many relationship, then you don't need a third entity (UserGroup). You only need users and groups entities. Nhibernate will handle the creation of the intermediate table by itself. But, I never use this approach. The approach you have taken (with the usergroup entity) is what I like much more because it gives you an additional flexibility. You never know when it will be necessary to have additional information in the relationship between users and groups (the date a user has been added to a group, who did create this relationship, etc.) So I would use the UsersGroups entity, but the way you create the relationship is a many-to-one between User and UserGroups and also a many-to-one between Group and UserGroups. This way you get what you want with the additional flexibility.