4

Entityという基本クラスがあります。

public class Entity
{
    public int Id {get;set;}
}

Customerというクラスがあるとしましょう。

public class Customer : Entity
{
    public string Name {get;set;}
}

ここで、NHibernate 3.3.1のコードによる規則ベースのマッピングを使用して、次のことを試します。

public static class DataHelper
{
    private static HbmMapping GetMappings()
    {
        var mapper = new CustomModelMapper(typeof(Entity));           

        return mapper.CompileMappingFor(
            typeof(DataHelper).Assembly.GetExportedTypes()
                .Where(x => x.IsSubclassOf(typeof(Entity))));
    }
}

アプリを実行しようとすると、「マップされていないクラスを拡張できません:エンティティ」というエラーが表示されます。Entityクラスをマップしたくありません。これは、いくつかの一般的なプロパティを継承するための単なる基本クラスです。マップされていないクラスを無視するようにNHibernateに指示するにはどうすればよいですか?参考までに、私のCustomModelMapperクラスを以下に示します。

CustomModelMapperクラスのコードを参照用に以下に示します

internal class CustomModelMapper : ConventionModelMapper
{
    private const int DEFAULT_STRING_LENGTH = 100;
    private Type baseType;

    public CustomModelMapper(Type baseType)
    {
        this.baseType = baseType;
    }

    public CustomModelMapper()
    {
        SetupInspectors();
    }

    protected override void AppendDefaultEvents()
    {
        base.AppendDefaultEvents();
        BeforeMapClass += OnBeforeMapClass;
        BeforeMapProperty += OnBeforeMapProperty;
        BeforeMapManyToOne += OnBeforeMapManyToOne;
        BeforeMapBag += OnBeforeMapBag;
        BeforeMapList += OnBeforeMapList;
        BeforeMapSet += OnBeforeMapSet;
    }

    protected void OnBeforeMapClass(IModelInspector modelInspector, Type type, IClassAttributesMapper classCustomizer)
    {
        classCustomizer.Id(type.GetProperty("Id"), m => m.Generator(Generators.Native));
    }

    protected void OnBeforeMapProperty(IModelInspector modelInspector, PropertyPath member, IPropertyMapper propertyCustomizer)
    {
        if (member.LocalMember.GetPropertyOrFieldType().IsEnum)
        {
            var type = member.LocalMember.GetPropertyOrFieldType();
            var genericType = typeof(EnumStringType<>).MakeGenericType(type);
            propertyCustomizer.Type(genericType, null);
        }

        if (member.LocalMember.GetPropertyOrFieldType() == typeof(string))
            propertyCustomizer.Length(DEFAULT_STRING_LENGTH);
    }

    protected void OnBeforeMapManyToOne(IModelInspector modelInspector, PropertyPath member, IManyToOneMapper propertyCustomizer)
    {
        propertyCustomizer.Cascade(Cascade.All);
        propertyCustomizer.Fetch(FetchKind.Join);
        propertyCustomizer.Lazy(LazyRelation.NoLazy);

        propertyCustomizer.Index(string.Format("IX{0}{1}",
            member.GetContainerEntity(modelInspector).Name,
            member.LocalMember.Name));
    }

    protected void OnBeforeMapBag(IModelInspector modelInspector, PropertyPath member, IBagPropertiesMapper propertyCustomizer)
    {
        propertyCustomizer.Cascade(Cascade.All);
        propertyCustomizer.Lazy(CollectionLazy.Extra);
        propertyCustomizer.Fetch(CollectionFetchMode.Subselect);
    }

    protected void OnBeforeMapList(IModelInspector modelInspector, PropertyPath member, IListPropertiesMapper propertyCustomizer)
    {
        propertyCustomizer.Cascade(Cascade.All);
        propertyCustomizer.Lazy(CollectionLazy.Extra);
        propertyCustomizer.Fetch(CollectionFetchMode.Subselect);
    }

    protected void OnBeforeMapSet(IModelInspector modelInspector, PropertyPath member, ISetPropertiesMapper propertyCustomizer)
    {
        propertyCustomizer.Cascade(Cascade.All);
        propertyCustomizer.Lazy(CollectionLazy.Extra);
        propertyCustomizer.Fetch(CollectionFetchMode.Subselect);
    }

    protected void SetupInspectors()
    {
        IsRootEntity((type, declared) =>
        {
            return baseType.Equals(type.BaseType);
        });

        IsEntity((type, declared) =>
        {
            return baseType.IsAssignableFrom(type) && !type.IsInterface;
        });

        IsVersion((member, declared) =>
        {
            return
                member.Name == "Version" &&
                member.MemberType == MemberTypes.Property &&
                member.GetPropertyOrFieldType() == typeof(int);
        });


        IsBag((member, declared) =>
        {
            if (member.GetPropertyOrFieldType().IsGenericType)
                return IsGenericType(member, typeof(ICollection<>));

            return false;
        });

        IsList((member, declared) =>
        {
            if (member.GetPropertyOrFieldType().IsGenericType)
                return IsGenericType(member, typeof(IList<>));

            return false;
        });

        IsSet((member, declared) =>
        {
            if (member.GetPropertyOrFieldType().IsGenericType)
                return IsGenericType(member, typeof(ICG.ISet<>));

            return false;
        });
    }

    protected static bool IsGenericType(MemberInfo member, Type targetType)
    {
        var type = member.GetPropertyOrFieldType();
        var generics = type.GetGenericInterfaceTypeDefinitions();
        return generics.Contains(targetType);
    }
}
4

1 に答える 1

3

問題はおそらくあなたのIsEntity慣習にあります。現在、Entityクラス自体に対して true を返します。別のチェックを追加するだけです:

IsEntity((type, declared) =>
{
    return baseType.IsAssignableFrom(type) && !type.IsInterface &&
           type != typeof(Entity); // <- skip Entity class
});

編集

また、CustomModelMapperクラスには 2 つのコンストラクターがあります。1 つは基本型を受け入れ、もう 1 つはデフォルトで を呼び出しますSetupInspectors()。ご覧のとおり、基本型を受け入れるコンストラクターを呼び出しているため、デフォルトのコンストラクターは呼び出されず、デフォルトのコンストラクターは呼び出されません...

そしてその結果は...あなたのSetupInspectors()メソッドも決して呼び出されません。

于 2012-07-09T21:07:49.467 に答える