NHibernate尝试在保存时将Entity强制转换为IDictionary [英] NHibernate tries to cast Entity to IDictionary when saving
问题描述
我有一个非常简单的设置:
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>
第三个问题可能是交换iesi
和System
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屋!