Получение ошибки «Связывание ссылок с не отображенным классом» при использовании интерфейсов в модели - PullRequest
0 голосов
/ 12 марта 2010

Я пытаюсь использовать функциональность автоматического в бегло, чтобы генерировать DDL для следующей модели и программы, но почему-то я продолжаю получать ошибка "Ассоциация ссылок на несопоставленный класс: IRole" при вызове метод GenerateSchemaCreationScript в NHibernate. Когда я заменяю тип ILists с реализацией интерфейсов (User и роль) все отлично работает. Что я здесь не так делаю? Как я могу бегло использовать реализованные версии IUser и IRole, как определено в единстве?

public interface IRole
{
   string Title { get; set; }
   IList<IUser> Users { get; set; }
}

   public interface IUser
   {
       string Email { get; set; }
       IList<IRole> Roles { get; set; }
   }

public class Role : IRole
{
   public virtual string Title { get; set; }
   public virtual IList<IUser> Users { get; set; }
}
public class User : IUser
{
   public virtual string Email { get; set; }
   public virtual IList<IRole> Roles { get; set; }
}

Я использую следующую программу для генерации DDL, используя GenerateSchemaCreationScript в NHibernate:

class Program
{
   static void Main(string[] args)
   {
       var ddl = new NHibernateSessionManager();
       ddl.BuildConfiguration();
   }
}

   public class NHibernateSessionManager
   {
       private ISessionFactory _sessionFactory;
       private static IUnityContainer _container;

       private static void InitContainer()
       {
           _container = new UnityContainer();
           _container.RegisterType(typeof(IUser), typeof(User));
           _container.RegisterType(typeof(IRole), typeof(Role));
       }

       public ISessionFactory BuildConfiguration()
       {
           InitContainer();
           return
Fluently.Configure().Database(MsSqlConfiguration.MsSql2008
                .ConnectionString("ConnectionString"))
                .Mappings(m => m.AutoMappings.Add(
                    AutoMap.AssemblyOf<IUser>()))
                .ExposeConfiguration(BuildSchema)
                .BuildSessionFactory();
       }

       private void BuildSchema(Configuration cfg)
       {
           var ddl = cfg.GenerateSchemaCreationScript(new
NHibernate.Dialect.MsSql2008Dialect());
           System.IO.File.WriteAllLines("Filename", ddl);
       }

   }

Ответы [ 2 ]

1 голос
/ 15 декабря 2010

Я в той же ситуации, что и вы. Используя ClassMap до того, как я узнал, вы можете сделать это с помощью Fluent, но я никогда раньше не использовал функцию AutoMapping. Я успешно смог сделать однозначное сопоставление с AutoMapper с помощью IReferenceConvention (см. Предыдущую статью SO post ).

Я столкнулся с той же проблемой, что и вы, где у меня есть отображение один ко многим, с чем у меня сейчас проблема. Есть интерфейс IHasManyConvention, который я начал изучать, но пока мне не повезло.

Если что-то трудно сделать, это не делает его неправильным, сопоставление с интерфейсами вызывающе имеет значение и может быть легко выполнено в исходных файлах сопоставления nHibernate или с помощью файлов сопоставления Fluents ClassMap. Я думаю, что как только люди начнут делать больше с функцией AutoMapping, будет больше постов в блоге.

EDIT

Я нашел временное решение, используя IAutoMappingOverride . Ниже приведен пример того, что вам нужно.

public class RoleAutoMappingOverride : IAutoMappingOverride<Role>
{
    public void Override(AutoMapping<Role> mapping)
    {
        mapping.HasMany<User>( x => x.Users ).KeyColumn( "User_id" );
    }
}

EDIT

Мой колледж разработал лучшее решение, которое использует соглашения вместо переопределения. Здесь описывается, как создать отдельный класс, но если вы посмотрите на пост SO, о котором я упоминал ранее, вы увидите, как это можно сделать общим.

public class Foo : IHasManyConvention
{
    public void Apply(IOneToManyCollectionInstance instance)
    {
        if (instance.ChildType == typeof(Role))
        {
            instance.Relationship.CustomClass<User>();
        }
    }
}

EDIT

Я превратил этот и другой пост в пост в блоге: http://bronumski.blogspot.com/2011/01/making-fluent-nhibernate-automapper.html

0 голосов
/ 12 марта 2010

Вы не можете предоставить интерфейс типа T в AssemblyOf<T>, вам нужно указать конкретный тип. Или вы можете использовать метод, который принимает сборку:

.Mappings(m => m.AutoMappings.Add(
                AutoMap.Assembly(myAssembly)))

Редактировать: Проблема в том, что ваши классы содержат коллекции типов интерфейса вместо типа класса. Я не знаю, возможно ли автоматизировать интерфейсы таким образом. Кроме того, я думаю, что использование интерфейсов для указания объектов домена редко имеет какое-либо значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...