2010-08-20 3 views
21

내 모델의 열거 형 속성 (System.DayOfWeek 인스턴스)을 정수 데이터베이스 필드에 매핑하려고합니다. 모델의 다른 enum 속성을 문자열에 매핑해야하므로 규칙을 정의하지 않으려합니다. 이 일 것으로 보인다 언뜻 보면 참으로매 플러시마다 업데이트를 일으키는 정수 매핑 열거 형

Map(x => x.DayOfWeek).CustomType<int>(); 

과 :

나는이 같은 유창 매핑을 사용 가능해야 이해합니다.

그러나이 방법으로 매핑 된 속성이있는 엔티티 인스턴스는 세션이 플러시 될 때마다 업데이트된다는 사실을 알았습니다.

이 플러시의 원인을 확인하려면 IPreUpdateEventListener를 설정하고 OldState와 엔터티의 상태를 검사합니다. 첨부 된 이미지를 참조하십시오. OldState에서 관련 객체는 int이며 State에서는 DayOfWeek입니다.

유형 속성이 지정되지 않은 HBM XML 매핑을 사용하는 경우이 문제가 발생하지 않습니다.

그래서 ...

이는 GenericEnumMapper에서 버그의 단점인가? FNH 매핑에 생성 된 HBM의 유형 속성을 지정하지 않도록 알리는 방법이 있습니까? 그렇지 않으면 NH가 열거 형에 사용하는 기본 유형을 지정할 수 있습니까? 내가 사용하는

alt text

+0

어떻게됩니까? 뉴 햄프셔는 그 자체로 문제를 해결해야합니까? –

+0

@ShaneC - 뉴 햄프셔,하지만 FNH의 동작은 기본적으로 열거 형으로 열거를 유지하려고하는 것입니다. –

답변

23

내 열거 형 규칙을 사용하면 이러한 문제가 발생하지 않습니다.

public class EnumConvention : IPropertyConvention, IPropertyConventionAcceptance 
{ 
    public void Apply(IPropertyInstance instance) 
    { 
     instance.CustomType(instance.Property.PropertyType); 
    } 

    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) 
    { 
     criteria.Expect(x => x.Property.PropertyType == typeof(AddressType) || 
      x.Property.PropertyType == typeof(Status) || 
      x.Property.PropertyType == typeof(DayOfWeek)); 
    } 
} 

그런 다음 일반처럼 속성을 매핑 할 수 있습니다 :

Map(x => x.DayOfWeek); 

편집 :은 INT 변환에 사용할 특정 열거 형을 선택하는 규칙을 업데이트했습니다. 여기에서 검사되지 않는 모든 열거 형은 문자열로 매핑됩니다. 실제로 테스트 할 대상을 조금 실험해야 할 수도 있습니다. 나는 재산 유형이 그것을 직접 할 것인지 확신 할 수 없다.

+0

문자열로 매핑하려는 대부분의 열거 형에 대해이 규칙을 재정의 할 수 있습니까? –

+0

가능합니다. 수락 부분에 모두 나와 있습니다. http://stackoverflow.com/questions/439003/how-do-you-map-an-enum-as-an-int-value-with-fluent-nhibernate/2716236#2716236 info – mhenrixon

+0

훌륭해, 나는 이것을 시도해 본다. 그리고 나는 그것이 필요한만큼 정확하게 행동한다. 도와 주셔서 감사합니다 @ Cz! –

4

한 가지 해결 방법은있는 int 백업 필드가하는 것입니다 NHibernate에 매핑을 위해 그것을 사용셔서.

NHibernate는 새로운 값을 이전 값과 비교하기 위해 캐스팅을해야 할 때마다 언제나 더러움으로 표시되어 플러시가 발생합니다.

+0

+1 : 열거 형 값을 나타내는 공개 속성을 가져온 다음 배킹 필드에서 int로 /에서 캐스팅합니다. 이것이 내가이 작업을 수행하는 방법입니다. – DanP

+0

이 아이디어는 마음에 들지 않습니다. 그런 다음 객체 내의 지속성 메커니즘에 대한 지식을 갖게됩니다. 그리고 CustomType <> 메서드는 IUserType에서 상속하는 형식을 제공하는 매핑 용이라고 생각했습니다. 내가 틀렸을지도 모른다. CustomType 매핑을 제거하고 GenericEnumMapper 기반 컨벤션으로 작업을 보냅니다. GenericEnumMapper에 대해 싫어하는 유일한 점은 enum의 항목을 재정렬 할 수 있다는 것입니다 (값을 설정하지 않는다고 가정 할 경우). – Rich

+0

감사의 인사, 이것을 받아들이려고 유혹, 그것은 안전하고 간단한 해결 방법 같다. –

0

DayOfWeek를 정수로 사용해야하는지 여부에 따라 다릅니다.

매핑의 일부로 캐스팅하는 경우 평등성은 항상 실패하며 속성은 더티로 표시됩니다.

아마지도 것 :

지도 (X => x.DayOfWeek) .CustomType를();

그리고 실제로 필요한 경우 DayOfWeek 값을 정수로 표시하는 읽기 전용 속성을 만듭니다. 그럼에도 불구하고 실제 유형으로 매핑하면 오류가 발생하지 않게됩니다.

0

대체 방법을 고려해 볼 수 있습니다. 필자는 Fabio Maulo의 well known instance types 사용법이 이러한 용도로 매우 유용하다는 것을 알았습니다. 기본 열거 형이 할 수있는 것을 확장하려고 시도 할 때 (예 : 지역화 된 설명 제공 등)

1

나를 위해 일한 간단한 방법은 매핑의 사용자 지정 유형을 int에서 PersistentEnumType으로 변경하는 것이 었습니다.

public class PersistentEnumType<T> : PersistentEnumType { 
    public PersistentEnumType() : base(typeof(T)) {} 
} 

그리고 이것은 당신의 엔티티 만 매핑에 대한 변경을 필요로하지 않습니다

Map(x => x.DayOfWeek) 
    .CustomType<PersistentEnumType<System.DayOfWeek>>(); 

사용하고, 별 특성에 적용 할 수 있습니다, 여러분의 인생을 더 쉽게 만들기 위해 일반 버전을 선언해야합니다 기초.

더보기 : here

+0

Orchard 확장 지점'ISessionConfigurationEvents'에서도 작동하는 멋진 솔루션입니다. 'ISessionConfigurationEvents.Created()'를 구현 한 클래스를 추가하고 거기에'defaultModel.Override (mapping => mapping.Map (x => x.DayOfWeek) .CustomType ())'를 넣으면됩니다. Orchard를 다시 시작하기 전에'mappings.bin'을 반드시 삭제해야합니다. – ViRuSTriNiTy

5

나는 파티에 늦었다는 것을 안다. 질문이 있은 지 2 년이 지났다. 나는이 우연히 한 이후, 나는 단지 나를 위해 문제를 해결 추가 할 수 있습니다

Map(x => x.DayOfWeek).CustomType<enumType>(); 

그것은 나를 위해 속임수를 썼는지 : 그 때마다 업데이트 중단했다.

자료 : 방금 CustomType없이하게되면, https://groups.google.com/forum/#!searchin/fluent-nhibernate/enum/fluent-nhibernate/bBXlDRvphDw/AFnYs9ei7O0J