0

我正在尝试使用流利的自动映射功能为以下模型和程序生成 DDL,但是当我在 NHibernate 中调用 GenerateSchemaCreationScript 方法时,我不断收到错误“关联引用未映射的类:IRole”。当我用接口(用户和角色)的实现替换 IList 的类型时,一切正常。我在这里做错了什么?如何流畅地使用 Unity 中定义的 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; }
}

我使用以下程序使用 NHibernate 中的 GenerateSchemaCreationScript 生成 DDL:

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

   }
4

2 回答 2

1

我和你的情况一样。在我知道您可以使用 Fluent 之前使用过 ClassMap,但我之前从未使用过 AutoMapping 功能。我已经成功地使用 IReferenceConvention 与 AutoMapper 进行了一对一的映射(请参阅之前的 SO帖子)。

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

仅仅因为有些事情很难做到,它不会出错,映射到接口无疑是有价值的,并且可以在原始的 nHibernate 映射文件或使用 Fluents ClassMap 映射文件中轻松完成。我认为一旦人们开始使用 AutoMapping 功能做更多事情,就会有更多的博客文章。

编辑

我找到了使用IAutoMappingOverride的临时解决方案。以下是您需要的粗略示例。

public class RoleAutoMappingOverride : IAutoMappingOverride<Role>
{
    public void Override(AutoMapping<Role> mapping)
    {
        mapping.HasMany<User>( 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>();
        }
    }
}

编辑

我现在已经把这篇文章和我的另一篇文章变成了一篇博文:http: //bronumski.blogspot.com/2011/01/making-fluent-nhibernate-automapper.html

于 2010-12-15T10:29:51.893 回答
0

您不能提供接口作为类型 T in AssemblyOf<T>,您需要提供具体类型。或者您可以使用接受组件的方法:

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

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

于 2010-03-12T17:48:23.343 回答