0

次のモデルとプログラムの DDL を生成するために fluent で automap 機能を使用しようとしていますが、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 との 1 対 1 マッピングを正常に実行できました (前の SO投稿を参照)。

私は今、あなたと同じ問題にぶつかりました.1対多のマッピングがあり、現在問題を抱えています. 私が見始めた 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 に答える