NHibernate尝试在保存时将Entity强制转换为IDictionary [英] NHibernate tries to cast Entity to IDictionary when saving

查看:72
本文介绍了NHibernate尝试在保存时将Entity强制转换为IDictionary的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的设置:

I have a very simple setup:

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>

但是,当我尝试创建角色并将其保存时:

But, when I try to create a role and save it:

[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'.

System.InvalidCastException: Unable to cast object of type 'UserManager.Model.Role' to type 'System.Collections.IDictionary'.

为什么NHibernate尝试将我的实体转换为IDictionary?而且,更重要的是:我该如何进行这项工作?我想念什么?

Why does NHibernate try to cast my Entity to an IDictionary? And, more importantly: How can I make this work? What am I missing?

推荐答案

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

I can see three problems here. Firstly you've used the mapping related to:

引用:

以下示例演示了使用地图(字典)的表示形式.首先,在映射文件中,必须声明一个实体名称,而不是(或附加一个)类名称:

The following examples demonstrates the representation using Maps (Dictionary). First, in the mapping file, an entity-name has to be declared instead of (or in addition to) a class name:

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

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

这就是我们在 entity-name 而不是 name 上方的映射中看到的内容.如示例所示,如果我们使用动态,那么我们将继续:

And this is what we can see in the mapping above entity-name instead of name. As the example shows if we use dynamic then we would continue:

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

请参阅:

引用:

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

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

(1) name: The fully qualified .NET class name of the persistent class (or interface), including its assembly name.

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

So, we cannot use dynamic mapping but the standard class mapping:

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

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

第二,将Enum与此元素映射映射到 int 列(我也使用permissionId作为列名表明它应该为int):

Secondly, the Enum should be mapped to int column with this element mapping (also I used permissionId as column name to show that it should be int):

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

总结这应该是有效的映射:

Summary this should be working mapping:

<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 .应该是这样的:

The third issue, could be swapping of iesi and System ISet. It should be like this:

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>();
    }
}

这篇关于NHibernate尝试在保存时将Entity强制转换为IDictionary的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆