NHibernate пытается привести Entity к IDictionary при сохранении

1

У меня очень простая настройка:

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 пытается передать мою Entity в IDictionary? И, что еще важнее: как я могу это сделать? Что мне не хватает?

Теги:
nhibernate

1 ответ

1
Лучший ответ

Здесь я вижу три проблемы. Во-первых, вы использовали отображение, относящееся к:

4.4. Динамические модели

Цитата:

Следующие примеры демонстрируют представление с помощью Maps (Dictionary). Во-первых, в файле сопоставления вместо имени (или в дополнение к) имени класса должно быть объявлено имя объекта:

<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
    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">

Во-вторых, Enum должен быть сопоставлен с столбцом 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>

Третьей проблемой может быть замена iesi и System 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>();
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню