与 NHIbernate 的多对多关系的 XML 映射文件

发布于 2024-10-25 01:05:28 字数 1016 浏览 1 评论 0原文

我有一个表 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白衬杉格子梦 2024-11-01 01:05:29

首先,您的 C# 类的设计似乎是错误的。它们并不反映您建立多对多关系的意图,而是反映一对多关系。由于每个组只允许一个用户通常没有意义,因此您应该将 UserGroup 类更改为

public class UserGroup
{
    [...]

    public virtual IList<User> Users { get; set; }
}

并更改映射:

<bag name="Users" table="UsersGroups" lazy="true" cascade="all" inverse="true" >
    <key column="GroupId"></key>
    <many-to-many column="UserId" class="User" />
</bag>

LookupUserGroup 类正确吗?在这个多对多关系的简单情况下,您应该只为三个表使用两个类。如果您有一个 User 类和一个 UserGroup 类,请删除 LookupUserGroup 类并将其替换为 User 中的映射.hbm.xml

User 类中的 AddGroup 方法看起来有点像这样:

public virtual void AddGroup(UserGroup userGroup)
{
    if(!this.UsersGroups.Contains(userGroup))
    {
         this.UsersGroups.Add(userGroup);
         userGroup.Users.Add(this); 
    }
}

intellisense 不提供 UserGroup 字段的原因很简单,因为您没有这样的字段。该字段称为 UsersGroups(应该是 UserGroups),是一个 IList

不幸的是,NHibernate 3.0 中当前的 Linq 提供程序并不真正支持您在此处尝试执行的查询类型。相反,您可以尝试使用 QueryOver。在你的情况下,它看起来像这样(改编自NHibernate QueryOver with ManytoMany

var result = Session.QueryOver<User>()
    .Right.JoinQueryOver<UserGroup>(x => x.UserGroups) // the .Right. might not be required
    .Where(c => c.Code == 1)
    .List();

我没有实现或测试任何这些,所以可能会有小错误。

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 to

public class UserGroup
{
    [...]

    public virtual IList<User> Users { get; set; }
}

and also change the mapping:

<bag name="Users" table="UsersGroups" lazy="true" cascade="all" inverse="true" >
    <key column="GroupId"></key>
    <many-to-many column="UserId" class="User" />
</bag>

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 a User class and a UserGroup class, get rid of the LookupUserGroup class and replace that in the mapping in the User.hbm.xml.

The AddGroup method in your User class would then look a little like this:

public virtual void AddGroup(UserGroup userGroup)
{
    if(!this.UsersGroups.Contains(userGroup))
    {
         this.UsersGroups.Add(userGroup);
         userGroup.Users.Add(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)

var result = Session.QueryOver<User>()
    .Right.JoinQueryOver<UserGroup>(x => x.UserGroups) // the .Right. might not be required
    .Where(c => c.Code == 1)
    .List();

I did not implement or test any of this, so there may be minor errors.

空城之時有危險 2024-11-01 01:05:29

克里斯,关于您的设计决策的简短说明。如果您确实想要拥有真正的多对多关系,那么您不需要第三个实体(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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文