Nhibernate 获取错误“;关联引用未映射类“;在模型中使用接口时

Nhibernate 获取错误“;关联引用未映射类“;在模型中使用接口时,nhibernate,unity-container,fluent,automapping,Nhibernate,Unity Container,Fluent,Automapping,我正在尝试使用fluent中的automap功能生成一个 以下模型和程序的DDL,但不知怎的,我一直 调用时出现错误“关联引用未映射的类:IRole” NHibernate中的GenerateSchemaCreationScript方法。当我替换 具有接口实现的IList类型(用户 (角色)一切正常。我做错了什么?我怎么能 使用所定义的IUser和IRole的实现版本 团结一致 public interface IRole { string Title { get; set; } I

我正在尝试使用fluent中的automap功能生成一个 以下模型和程序的DDL,但不知怎的,我一直 调用时出现错误“关联引用未映射的类:IRole” NHibernate中的GenerateSchemaCreationScript方法。当我替换 具有接口实现的IList类型(用户 (角色)一切正常。我做错了什么?我怎么能 使用所定义的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; }
}
公共接口IRole
{
字符串标题{get;set;}
IList用户{get;set;}
}
公共接口IUser
{
字符串电子邮件{get;set;}
IList角色{get;set;}
}
公共类角色:IRole
{
公共虚拟字符串标题{get;set;}
公共虚拟IList用户{get;set;}
}
公共类用户:IUser
{
公共虚拟字符串电子邮件{get;set;}
公共虚拟IList角色{get;set;}
}
我使用以下程序使用 NHibernate中的GenerateSchemaCreationScript:

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

   }
类程序
{
静态void Main(字符串[]参数)
{
var ddl=新的NHibernateSessionManager();
BuildConfiguration();
}
}
公共类NHibernateSessionManager
{
私人ISessionFactory(sessionFactory);;
专用静态IUnityContainer\u容器;
私有静态void InitContainer()
{
_容器=新的UnityContainer();
_RegisterType(typeof(IUser),typeof(User));
_RegisterType(typeof(IRole)、typeof(Role));
}
公共ISessionFactory构建配置()
{
InitContainer();
返回
fluntly.Configure().Database(MsSqlConfiguration.MsSql2008
.ConnectionString(“ConnectionString”))
.Mappings(m=>m.AutoMappings.Add(
AutoMap.AssemblyOf()))
.ExposeConfiguration(构建架构)
.BuildSessionFactory();
}
私有void BuildSchema(配置cfg)
{
var ddl=cfg.GenerateSchemaCreationScript(新建
NHibernate.dialogue.mssql2008dialogue());
System.IO.File.writeAllines(“文件名”,ddl);
}
}

您不能像在
AssemblyOf
中的类型t那样提供接口,您需要提供一个具体的类型。或者您可以使用接受assemply的方法:

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

编辑:问题是类包含接口类型的集合,而不是类类型的集合。我不知道是否有可能以这种方式自动映射接口。另外,我认为使用接口来指定域对象几乎没有任何价值。

我和你的处境相同。在我知道你可以用Fluent来实现这一点之前,我已经使用了类映射,但我以前从未使用过自动映射功能。我已经成功地使用IReferenceConvention(参见前面的SO)使用AutoMapper进行了一对一映射

我现在遇到了和你一样的问题,我有一对多的映射,我现在遇到了一个问题。有一个IHasManyConvention接口,我已经开始查看,但到目前为止还没有找到

仅仅因为有些事情很难做到,但不会出错,到接口的映射很有价值,可以在原始nHibernate映射文件中或通过使用Fluents类映射文件轻松完成。我认为一旦人们开始更多地使用自动映射功能,就会有更多的博客文章

编辑

我已经找到了一个临时解决方案,使用了一个。下面是一个粗略的例子,你需要什么

public class RoleAutoMappingOverride : IAutoMappingOverride<Role>
{
    public void Override(AutoMapping<Role> mapping)
    {
        mapping.HasMany<User>( x => x.Users ).KeyColumn( "User_id" );
    }
}
公共类RoleAutoMappingOverride:IAutoMappingOverride
{
公共无效替代(自动映射)
{
mapping.HasMany(x=>x.Users).KeyColumn(“User_id”);
}
}
编辑

我的一所学院已经想出了一个更好的解决方案,使用约定而不是覆盖。这涵盖了如何做一个单一的类,但如果你看看我之前提到的SO帖子,你会发现这是如何变得通用的

public class Foo : IHasManyConvention
{
    public void Apply(IOneToManyCollectionInstance instance)
    {
        if (instance.ChildType == typeof(Role))
        {
            instance.Relationship.CustomClass<User>();
        }
    }
}
公共类Foo:IHasManyConvention
{
public void Apply(IOneToManyCollectionInstance实例)
{
if(instance.ChildType==typeof(Role))
{
instance.Relationship.CustomClass();
}
}
}
编辑

我现在已经将这篇文章和我的另一篇文章变成了一篇博客文章:

对此感到抱歉-它当然应该是:.Mappings(m=>m.AutoMappings.Add(AutoMap.AssemblyOf()))但我的问题仍然是一样的,我在以下方面遇到了错误:公共虚拟IList用户{get;set;}和公共虚拟IList角色{get;set;}有什么办法可以解决这个问题吗?根据这一点,可以告诉NHibernate它应该为接口使用哪个实现(使用映射文件)。我只是想知道是否有一种方法可以让Fluent中的automapping知道同样的事情?@Bjarke-你可以这样做,看看我的答案,然后发帖子。