유창한 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.