유창한 NHibernate를 사용하여 enum을 int 값으로 어떻게 매핑합니까?


88

질문은 실제로 모든 것을 말합니다. 기본값은으로 매핑하는 string것이지만 int.

나는 현재 PersistenceModel그것이 차이가 있다면 내 규칙을 설정하는 데 사용하고 있습니다. 미리 감사드립니다.

업데이트 트렁크에서 최신 버전의 코드를 가져 오는 것이 내 문제를 해결했다는 사실을 발견했습니다.


5
문제를 직접 해결했다면 답한 다음 정답으로 표시하여 향후 검색자가 찾을 수 있도록해야합니다.
— Jeff Martin

답변을 게시 해 주시겠습니까?
— mxmissile

다들. 지연 돼서 죄송합니다. 나는 최신 버전의 라이브러리가 필요했기 때문에 질문이 아닌 질문으로 무엇을해야할지 잘 모르겠습니다.
— Garry Shutler

2
Google 봇을위한 음식 : 열거 형 매핑을 구현하기 전에 "컬렉션로드에 대한 불법 액세스"를 얻었습니다.
— 4imble 2010

답변:


84

이 규칙을 정의하는 방법은 때때로 변경되었습니다. 지금은 다음과 같습니다.

public class EnumConvention : IUserTypeConvention
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType.IsEnum);
    }

    public void Apply(IPropertyInstance target)
    {
        target.CustomType(target.Property.PropertyType);
    }
}

4
이것은 유창한 nhibernate의 최신 버전에 대한 정답입니다
— Sean Chambers

충돌. ^^ Sean이 말한 것.
— Martin Suchanek

1
이것은 모든 열거 형 유형에서 잘 작동하는 것처럼 보이지만 일부는 문자열로, 일부는 정수로 원하면 어떻게 될까요? 속성 매핑 수준에서 구성 할 수 있어야한다고 생각합니다.
— UpTheCreek

4
nullable 열거 형을 허용하도록이를 확장하는 아래 @SztupY의 답변을 참조하십시오. stackoverflow.com/questions/439003/…
— Jon Adams

45

그래서 앞서 언급했듯이 최신 버전의 Fluent NHibernate를 트렁크에서 가져와 내가 있어야 할 곳으로 이동했습니다. 최신 코드가있는 열거 형 매핑의 예는 다음과 같습니다.

Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus));

사용자 지정 형식은 .NET Framework를 사용하는 대신 열거 형의 인스턴스로 처리되도록합니다 GenericEnumMapper<TEnum>.

나는 실제로 문자열을 유지하는 열거 매퍼와 규칙으로 설정할 수 있어야 할 것처럼 보이는 int를 유지하는 매퍼 사이에서 변경할 수 있도록 패치를 제출하는 것을 고려하고 있습니다.


이것은 나의 최근 활동에서 튀어 나왔고 Fluent NHibernate의 최신 버전에서 상황이 더 쉽게 변경되었습니다.

모든 열거 형을 정수로 매핑하려면 이제 다음과 같은 규칙을 만들 수 있습니다.

public class EnumConvention : IUserTypeConvention
{
    public bool Accept(IProperty target)
    {
        return target.PropertyType.IsEnum;
    }

    public void Apply(IProperty target)
    {
        target.CustomTypeIs(target.PropertyType);
    }

    public bool Accept(Type type)
    {
        return type.IsEnum;
    }
}

그런 다음 매핑은 다음과 같아야합니다.

Map(quote => quote.Status);

다음과 같이 Fluent NHibernate 매핑에 규칙을 추가합니다.

Fluently.Configure(nHibConfig)
    .Mappings(mappingConfiguration =>
    {
        mappingConfiguration.FluentMappings
            .ConventionDiscovery.AddFromAssemblyOf<EnumConvention>();
    })
    ./* other configuration */

3
기본값은 "int mode"입니다. 누가 열거 형을 문자열로 유지합니까?!
— Andrew Bullock

4
이미 거기에 문자열 값이있는 레거시 데이터베이스 일 수 있습니다.
— Chris Haines

4
+1 hainesy. @ Andrew Bullock : 질문에 대한 답변 : 실제 데이터베이스를 다루는 모든 사람.
— Sky Sanders

FN에 IProperty 인터페이스가 있습니까?
— Tien Do

40

nullable 열거 형 (예 :)을 잊지 마세요 ExampleEnum? ExampleProperty! 별도로 확인해야합니다. 다음은 새로운 FNH 스타일 구성으로 수행되는 방법입니다.

public class EnumConvention : IUserTypeConvention
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType.IsEnum ||
            (x.Property.PropertyType.IsGenericType && 
             x.Property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) &&
             x.Property.PropertyType.GetGenericArguments()[0].IsEnum)
            );
    }

    public void Apply(IPropertyInstance target)
    {
        target.CustomType(target.Property.PropertyType);
    }
}

4
+1이 추가! 첫 번째 버전은 nullable 열거 형에 대해 작동하지 않습니다 (문자열로 남아 있음).
— longda

@SztupY 데이터베이스의 열 유형은 int? 그리고 유형이 플래그를 허용 할 때? 좋아요 :MyEnum.Active | MyEnum.Paused
— ridermansb

@RidermandeSousaBarbosa : 플래그 확인 : stackoverflow.com/questions/2805661/…
— SztupY

25

이것은 int 값으로 enum 속성을 매핑 한 방법입니다.

Map(x => x.Status).CustomType(typeof(Int32));

나를 위해 작동합니다!


2
간단한 답을 제공 주셔서 감사합니다
— 마이크

이것에 대한 유일한 단점은 모든 열거 형에 적용하는 것을 기억해야한다는 것입니다. 그것이 관습이 만들어진 것입니다.
— Garry Shutler

이것은 읽기에는 작동하지만 기준 쿼리를 시도하면 실패했습니다. 컨벤션 설정 (이 질문에 대한 답변 참조)은 내가 시도한 모든 경우에서 작동했습니다.
— Thomas Bratt

나는 그것이 훌륭하다고 생각했지만 이것은 문제를 일으킬 것입니다. nhforge.org/blogs/nhibernate/archive/2008/10/20/...
— UpTheCreek

@UpTheCreek 수정되었습니다 지금은 NH 팀에서 제임스 그레고리에서 권장하는 것 같다 : mail-archive.com/fluent-nhibernate@googlegroups.com/...
— 일리아 년 Kogan

1

Automapping (및 잠재적으로 IoC 컨테이너)과 함께 Fluent NHibernate를 사용하는 경우 :

는 IUserTypeConvention@ 같다 줄리앙 의 대답 위 : https://stackoverflow.com/a/1706462/878612

public class EnumConvention : IUserTypeConvention
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType.IsEnum);
    }

    public void Apply(IPropertyInstance target)
    {
        target.CustomType(target.Property.PropertyType);
    }
}

Fluent NHibernate Automapping 구성은 다음과 같이 구성 할 수 있습니다.

    protected virtual ISessionFactory CreateSessionFactory()
    {
        return Fluently.Configure()
            .Database(SetupDatabase)
            .Mappings(mappingConfiguration =>
                {
                    mappingConfiguration.AutoMappings
                        .Add(CreateAutomappings);
                }
            ).BuildSessionFactory();
    }

    protected virtual IPersistenceConfigurer SetupDatabase()
    {
        return MsSqlConfiguration.MsSql2008.UseOuterJoin()
        .ConnectionString(x => 
             x.FromConnectionStringWithKey("AppDatabase")) // In Web.config
        .ShowSql();
    }

    protected static AutoPersistenceModel CreateAutomappings()
    {
        return AutoMap.AssemblyOf<ClassInAnAssemblyToBeMapped>(
            new EntityAutomapConfiguration())
            .Conventions.Setup(c =>
                {
                    // Other IUserTypeConvention classes here
                    c.Add<EnumConvention>();
                });
    }

* 그러면 CreateSessionFactoryCastle Windsor (PersistenceFacility 및 설치 프로그램 사용)와 같은 IoC에서 쉽게 사용할 수 있습니다. *

    Kernel.Register(
        Component.For<ISessionFactory>()
            .UsingFactoryMethod(() => CreateSessionFactory()),
            Component.For<ISession>()
            .UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
            .LifestylePerWebRequest() 
    );


0

DB 테이블에서 값을 int / tinyint로 유지해야합니다. 열거 형을 매핑하려면 매핑을 올바르게 지정해야합니다. 아래 매핑 및 열거 형 샘플을 참조하십시오.

매핑 클래스

공용 클래스 TransactionMap : ClassMap 트랜잭션
{
    공용 TransactionMap ()
    {
        // 기타 매핑
        .....
        // 열거 형 매핑
        Map (x => x.Status, "상태") .CustomType ();

        Table ( "거래");
    }
}

열거 형

공개 열거 형 TransactionStatus
{
   대기 = 1,
   처리됨 = 2,
   롤백 = 3,
   차단됨 = 4,
   환불 됨 = 5,
   이미 처리됨 = 6,
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.