我是nhibernate的新手,如果在其他地方得到解答,我很抱歉,但我一直在寻找最近几个小时,但找不到有效的解决方案。
一些背景知识: 我正在尝试编写一个管理区域,其中有用户和站点,用户可以访问多个站点 - 但每个站点具有不同的权限级别。
理想情况下,我希望我的课程看起来像这样。
namespace MyApp.Users
{
public class User
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Password { get; set; }
public virtual IList<AdminUserSite> Sites { get; set; }
}
public class AdminUserSite
{
public virtual int UserTypeId { get; set; }
public virtual Site AdminSite { get; set; }
public virtual IList<Permission> Permissions { get; set; }
}
public class Permission
{
public virtual int Id { get; set; }
public virtual int AreaID { get; set; }
public virtual bool CanView { get; set }
public virtual bool CanEdit { get; set }
}
}
namespace MyApp.Sites
{
public class Site
{
public virtual int Id { get; set; }
public virtual string Title { get; set; }
}
}
我的数据库架构看起来像这样
f_user
{
f_user_id (int, PK)
name (nvarchar(50))
password (nvarchar(25))
}
f_user_site
{
f_user_id (int, PK)
f_site_id (int, PK)
d_user_type_id (int)
}
f_perm
{
f_perm_id (int, PK)
f_site_id (int)
f_user_id (int)
d_area_id (int)
can_read (bit)
can_write (bit)
}
f_site
{
f_site_id (int, PK)
title (nvarchar(50))
}
hibernate映射文件目前看起来像: Users.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="MyApp"
namespace="MyApp.Users"
default-lazy="true">
<class name="User" table="f_user">
<id name="Id" column="f_user_id">
<generator class="identity" />
</id>
<property name="Name" column="name" />
<property name="Password" column="password" />
<bag name="Sites" table="f_user_site" inverse="true" cascade="all-delete-orphan">
<key column="f_user_id"/>
<one-to-many class="AdminUserSite"/>
</bag>
</class>
<class name="Permission" table="f_perm">
<id name="Id" column="f_perm_id">
<generator class="identity" />
</id>
<property name="AreaId" column="d_area_id" />
<property name="CanView" column="can_read" />
<property name="CanEdit" column="can_write" />
</class>
<class name="AdminUserSite" table="f_user_site">
<property name="UserTypeId" column="d_user_type_id" />
<many-to-one name="Site" class="MyApp.Sites.Site, MyApp.Sites" foreign-key="f_site_id"></many-to-one>
</class>
</hibernate-mapping>
和Sites.hbm.xml是
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="MyApp"
namespace="MyApp.Sites"
default-lazy="true">
<class name="Site" table="f_site">
<id name="Id" column="f_site_id">
<generator class="identity" />
</id>
<property name="Title" column="title" />
</class>
</hibernate-mapping>
单独地,用户,权限和站点类都可以正常映射 - 但我无法弄清楚AdminUserSite应该是什么,我甚至还没有尝试将权限列表放在那里。
有没有人有任何想法?
非常感谢任何帮助。 Saan
答案 0 :(得分:0)
我认为您需要对数据库架构进行一些处理。我认为AdminUserSite表是你的问题。
首先,找出你的实体(这些应该是简单的名词,这就是为什么AdminUserSite对我来说不合适的原因。)
实体:用户,权限,网站,SiteArea
接下来,找出关系:
1用户有很多权限
1 SiteArea有许多权限
1网站有很多SiteAreas
(希望我说得对:))
之后,你的hbm和表应该更自然地流动。
请记住,通常每个实体都有1个表,除非你有很多关系(在这种情况下你需要一个连接表)。
答案 1 :(得分:0)
通常,关系表映射如下所示:
<class name="AdminUserSite" table="f_user_site">
<composite-id >
<key-many-to-one name="Site" column="f_site_id" class="Site" />
<key-many-to-one name="User" column="f_user_id" class="User"/>
</composite-id>
</class>
通过这种方式,您可以通过其关系对象访问站点或用户,或者按照基于站点或用户的条件加载关系对象。
顺便说一下,如果你的Permission对象包含对用户和站点的引用,你可能不需要AdminUserSite关系,那么权限映射已经完成了。
关于您的评论编辑 在两个位置复制相同信息的种类。
由于NHibernate类似所有ORM-都具有第一级缓存,因此如果可以通过两种方式访问对象,则无需担心。您只需确保映射对于优化和设计应用程序非常有用。
在这种情况下,它不是'复制'而是参考。如果从同一个NHibernate会话加载/检索,则该对象在两个点中是相同的。 如果对象具有逻辑(即直接方式和交叉关系方式),则以两种方式访问对象并不是异端。
这是大多数数据层工作,以提供正确方法以正确的方式访问正确的对象:)