1

NHibernate 4.0.2.4000 を使用しています。PropertyInfo を使用してマッピングを作成しています。

public class MyClassMapping<T> : ClassMapping<T> where T : BaseEntity
{
    public MyClassMapping()
    {
        ....
        PropertyInfo[] props = typeof(T).GetProperties();
        foreach (PropertyInfo prop in props)
        {
            /* some code */

            Bag(prop.Name, collectionMapping =>
            {
                collectionMapping.Table(prop.Name + "_" + classType.Name +"_Rel");
                collectionMapping.Key(k => k.Column(prop.Name + "_Id"));
            },
            mapping => mapping.ManyToMany(p => p.Column(classType.Name + "_Id")));

            /* some code */
        }
    }
}

しかし、「バッグ」はエラーを返します。メソッド [...] の型引数は、使用法から推測できません。型引数を明示的に指定してみてください。使用する必要があることはわかっていますBag<TElement>()が、TElement がありません。

メソッド ( Id()Property()) はうまく機能します。

私はそれを使用しようとしました:

this.GetType()
    .GetMethod("Bag")
    .MakeGenericMethod(prop.PropertyType)
    .Invoke(this, new object[]{ prop.Name, [...], [...] });

しかしデリゲートは複雑すぎます。

メソッドManyToOne()は機能します:

public class MyClassMapping<T> : ClassMapping<T> where T : BaseEntity
{
    public MyClassMapping()
    {
        ....
        PropertyInfo[] props = classType.GetProperties();
        foreach (PropertyInfo prop in props)
        {
            /* some code */

            RegisterManyToOneMappingByMember(prop, map =>
            {
                map.Column(aManyToOne.Name);
                ....
            });

            /* some code */
        }
    }

    protected virtual void RegisterManyToOneMappingByMember(MemberInfo property, Action<IManyToOneMapper> mapping)
    {
        RegisterManyToOneMapping<BaseEntity>(mapping, property);
    }

多分誰かが別の解決策を知っていますか?メモリ内のxmlでマップを動的に実行することを提案しないでください。ありがとう。

4

1 に答える 1

1

ここでの方法は、Bag定義と反射を分割することです。

したがって、最初にメソッドを作成しBag、ジェネリック引数を消費しますTElement:

public virtual void CreateBag<TElement>(PropertyInfo prop, Type classType)
{
    Bag<TElement>(prop.Name,
    collectionMapping =>
    {
        collectionMapping.Table(prop.Name + "_" + classType.Name + "_Rel");
        collectionMapping.Key(k => k.Column(prop.Name + "_Id"));
    },
    mapping => mapping.ManyToMany(p => p.Column(classType.Name + "_Id")))
    ;
}

そして今、調整されたイテレータ:

var classType = ... // current class type 
PropertyInfo[] props = classType.GetProperties();
foreach (PropertyInfo prop in props)
{
    // here ... just find out if this property
    // is candidate for Bag mapping
    var isBagCandidate = prop.PropertyType.GenericTypeArguments.Length > 0
        && !prop.PropertyType.IsValueType
        && ... // these checks should be adjusted
        ;

    if (!isBagCandidate)
    {
        continue; // do not continue to Bag mapping
    }

    // now we just get reference to our method defined above
    MethodInfo method = typeof(MyClassMapping).GetMethod("CreateBag");
    MethodInfo generic = method.MakeGenericMethod(
                                           prop.PropertyType.GenericTypeArguments[0]);

    // and call it, with needed params
    generic.Invoke(this, new object[] { prop, classType });
}
于 2014-11-23T06:44:49.307 に答える