NHibernate尝试在保存时将Entity转换为IDictionary

时间:2014-06-13 13:29:41

标签: c# nhibernate

我的设置非常简单:

public class Role
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual ISet<Permission> Permissions { get; set; }

    public Role()
    {
        Permissions = new HashSet<Permission>();
    }
}

public enum Permission
{
    ACCESS_USER_MANAGER, [... and many more]
}

根据映射文件:

<class entity-name="UserManager.Model.Role" table="roles">
    <id name="Id" type="int">
        <generator class="identity" />
    </id>

    <property name="Name" column="name" type="string"/>

    <set name="Permissions" table="permissions">
        <key column="role"/>
        <element column="name" type="string"/>
    </set>

</class>

但是,当我尝试创建一个角色并保存它时:

[TestMethod]
public void TestRoles()
{
    ITransaction transaction = _session.BeginTransaction();
    Role role = new Role();
    role.Name = "Test-Role";
    role.Permissions.Add(Permission.ACCESS_USER_MANAGER);
    _session.Save(role);
    transaction.Commit();
}

我得到一个例外:

  

System.InvalidCastException:无法将“UserManager.Model.Role”类型的对象强制转换为“System.Collections.IDictionary”。

为什么NHibernate试图将我的实体投射到IDictionary?而且,更重要的是:我怎样才能做到这一点?我错过了什么?

1 个答案:

答案 0 :(得分:1)

我在这里可以看到三个问题。首先,您使用了与以下内容相关的映射:

4.4. Dynamic models

引用:

  

以下示例演示了使用地图(字典)的表示。首先,在映射文件中,必须声明实体名称而不是(或除了)类名称之外:

     

<hibernate-mapping>
     <class entity-name="Customer">
     ...

我们可以在 entity-name 上方的映射中看到这一点,而不是 name 。如示例所示,如果我们使用动态,那么我们将继续:

// Create a customer
var frank = new Dictionary<string, object>();
frank["name"] = "Frank";
...
// Save customer
s.Save("Customer", frank);

请参阅:

5.1.3. class

引用:

<class
    name="ClassName"                              (1)
    ...
  

(1)name:持久化类(或接口)的完全限定的.NET类名,包括其程序集名称。

因此,我们不能使用动态映射,而是使用标准类映射:

// Instead of this
// <class entity-name="UserManager.Model.Role" table="roles">

// we should use this
<class name="UserManager.Model.Role" table="roles">

其次,枚举应该映射到 int 列,并使用此元素映射(我也使用permissionId作为列名来表明它应该是int )

<element column="permissionId" type="UserManager.Model.Permission"/>

总结这应该是工作映射:

<class name="UserManager.Model.Role" table="roles">
    <id name="Id" type="int">
        <generator class="identity" />
    </id>

    <property name="Name" column="name" type="string"/>

    <set name="Permissions" table="permissions">
        <key column="role"/>
        //<!--<element column="name" type="string"/>-->
        <element column="permissionId" type="UserManager.Model.Permission"/>
    </set>

</class>

第三个问题可能是交换iesiSystem ISet 。它应该是这样的:

using Iesi.Collections.Generic;
public class Role
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual ISet<Permission> Permissions { get; set; }

    public Role()
    {
      //Permissions = new HashSet<Permission>();
        Permissions = new HashedSet<Permission>();
    }
}