2009-09-11 2 views
0

나는 기존의 클래스를 그대로 유지하고 싶습니다.NHibernate : 기존 public int 필드를 레코드 Id로 사용

class FooMap : ClassMap<Foo> 
{ 
    Id(x => x.Id); 
    ... 
} 

잘못된 캐스트 예외 세션 공장 결과를 건물 :

class Foo 
{ 
    public int Id; 
    ... 
} 

나는 다음과 같은 ClassMap 있습니다. 엔티티 클래스에 "public virtual int Id {get; private set;}"속성이있는 경우 설치가 작동합니다. 나는 nhibernate ID로 "public int Id"필드를 사용할 수 있는지 배우는 것에 관심이 있습니다. 현재 FluentNHibernate이 할 수없는 것처럼 항상 속성을 다루는 excepts 때문에

편집

그것은 보인다. NHibernate xml 매핑을 혼합하여이 작업을 수행 할 수 있습니다. Details on the mailing list.

답변

1

나는 또한이 질문에 대한 답변을 메일 목록 (cross posted there)에 넣었지만 여기서도 설명하는 것이 유용 할 것이라고 생각했습니다.

불행히도 Fluent NHibernate는 현재 Property를 참조하는 람다 식을이 가정에 전달한다고 가정합니다 (이 가정은 PropertyInfo 유형에 크게 의존 함).

Id(x => x.Id).Access.Field(); 

우리는 PropertyInfo에 대한 의존도를 제거하여 결국이 문제를 해결하려는 : 이드 필드보다는 속성이 경우이의 결과로,이 라인은 런타임에 실패합니다.

2

클래스 레벨에서 지연로드를 사용하지 않아야한다고 지정하면 (즉, NHibernate가 객체에 대한 프록시를 생성하지 않아야 함) 모든 가상 속성을 가상으로 만들 필요는 없습니다.

기본적으로 NHibernate는 DB에서 엔티티 인스턴스를 검색 할 때 프록시를 생성합니다. 즉, Id 필드 만 채워진 '빈'개체를 반환합니다. 해당 개체의 다른 속성이 필요할 때만 개체 자체가 검색됩니다.

이 동작을 원하지 않으면 클래스 수준에서 '지연 = false'를 지정하여 해제 할 수 있습니다. 내가 유창함에 그것을하는 방법을 모른다,

<class name="MyClass" table="sometable" lazy="false"> 
</class> 

을하지만,있다 - HBM으로 매핑 파일, 당신은 이런 식으로 그것을 할 나는 아직 유창하지 못했습니다.

편집 : 반드시 NHibernate는 필드를 설정해야합니다. 이를 위해, 당신은 두 가지 옵션이 있습니다 :

  • 첫 번째 옵션은 이미 개인 세터에게
  • 초 옵션을 제공하여 준 솔루션은 자동 속성을 사용하고, 같은 당신의 재산을 만들 수 없습니다입니다 이 :

    public class MyClass 
    { 
    
        private int _id; 
    
        public int Id { get { return _id; } } 
    } 
    

    그런 다음, 당신의 매핑에 당신은 그 값을 설정할 때 NHibernate에 대신 재산의 지원 필드를 사용하도록 정의해야합니다. Iin이 HBM 매핑 파일, 당신은 이런 식으로 작업을 수행합니다

    <property name="Id" column="columnname" access="field.camelcase-underscore" /> 
    

    당신이 볼 수 있듯이, 당신은 NHibernate에이 필드를 사용하도록 지정하고, 주어진 네이밍 전략을 적용하여 필드를 찾을 수 있습니다. 이 경우 필드의 이름은 속성과 같지만 접두사는 밑줄로 표시되며 camelcase (첫 번째 문자는 소문자)로 작성됩니다. (정체성, 그것은 잘 작동한다 : 대신 속성의 필드를 매핑하기 위해

    <id name="Id" column="..." access="field.camelcase-underscore" /> 
        <generator ... /> 
    </id> 
    

, 당신은 매핑 파일에

access="field" 

을 정의해야하지만, 다시. 내가 급히 유창함을 살펴해야 추측 ... 그것은 유창함 사용하는 방법을 모르는

편집 :.,자, Fluent를 다운로드했습니다. :) 이렇게 할 수 없습니까?

public class FooMap : ClassMap<Foo> 
{ 
    public FooMap() 
    { 
     Id(x => x.Id).Access.Field(); 
    } 
} 

?

+0

아, 미안하지만 분명하지 않은 경우 죄송합니다. 내 질문에 대한 "클래스 Foo 수정하지 않고 Foo 형식의 개체를 유지할 수 있도록 FooMap을 정의 할 수 있습니다." – anthony

+0

그래서 재산 대신 필드가있는 클래스가 있다는 것을 의미합니까? –

+0

. 나는 그것을 그대로 사용할 수 있을지 궁금해한다. 대답이 '아니오'인 경우 서브 클래스를 만들고 원하는대로 수행 할 수 있지만 가능하지 않도록하고 싶습니다. – anthony

관련 문제