Getting error “Association references unmapped class” when using interfaces in model

丶灬走出姿态 提交于 2020-01-03 05:43:04

问题


I'm trying to use the automap functionality in fluent to generate a DDL for the following model and program, but somehow I keep getting the error "Association references unmapped class: IRole" when I call the GenerateSchemaCreationScript method in NHibernate. When I replace the type of the ILists with the implementation of the interfaces (User and Role) everything works fine. What am I doing wrong here? How can I make fluent use the implemented versions of IUser and IRole as defined in Unity?

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

I use the following program to generate the DDL using the GenerateSchemaCreationScript in 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);
       }

   }

回答1:


I am in the same situation as you. Having used the ClassMap before I know you can do this with Fluent but I had never used the AutoMapping feature before. I have successfully been able to do a one to one mapping with the AutoMapper using an IReferenceConvention (see previous SO post).

I have now hit the same problem as you where I have a one to many mapping which I am now having a problem with. There is an IHasManyConvention interface which I have started to look at but have had no luck as of yet.

Just because some thing is hard to do it doesn't make it wrong, mapping to interfaces defiantly has value and can easily be done in the raw nHibernate mapping files or by using Fluents ClassMap mapping files. I think once people start do more with AutoMapping feature there will be more blog posts.

EDIT

I have found an interim solution using an IAutoMappingOverride. Below is a rough example of what you need.

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

EDIT

A college of mine has worked out a better solution that uses conventions instead of the override. This covers how to do a single class but if you look at the SO post I mentioned before you can see how this could be made generic.

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

EDIT

I have now turned this and my other post into a blog post: http://bronumski.blogspot.com/2011/01/making-fluent-nhibernate-automapper.html




回答2:


You can't provide an interface as the type T in AssemblyOf<T>, you need to provide a concrete type. Or you could use the method that accepts an assemply:

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

Edit: The problem is that your classes contain collections of interface types instead of class type. I don't know if it's possible to automap interfaces in this manner. Also, I think there's rarely any value in using interfaces to specify domain objects.



来源:https://stackoverflow.com/questions/2433234/getting-error-association-references-unmapped-class-when-using-interfaces-in-m

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!