2009-03-30 2 views
19

우리 회사에서하고있는 프로젝트에 대해 NHibernate를 프로 포지션하고 있는데 NHibernate가 Criteria 쿼리 언어를 사용할 때 테이블의 특정 열만 검색하도록 최적화 할 수 있는지 알고 싶습니다.Critera 쿼리를 사용할 때만 특정 열을 검색합니까?

예를 들면. 예를 들어, 30 개의 열이있는 테이블이 있고이 테이블에 대해 1 대 1로 일치하는 NHibernate를 사용하여 개체에 매핑되어 있다고 가정 해 봅시다. 그러나 시스템의 특정 기능의 경우 해당 열 중 두 개만 신경 써야합니다.

이제는 HQL을 사용할 수 있고 이것을 수행 할 CreateQuery을 수행 할 수 있다는 것을 알고 있습니다. 그러나이를 위해서는 선택적으로 검색 할 필드의 각 조합에 대해 생성자를 만들어야합니다. 런타임까지 누락 된 생성자를 잡아 내지 않으므로 유지 관리 관점에서 볼 때 커다란 고통이 될 수 있습니다.

HQL에서 직접 SQL 쿼리 대신 매개 변수화 된 SQL을 생성하므로 Criteria 쿼리 언어를 좋아합니다. 특정 열을 포함하지 않는 "제외"모델이 있지만 대부분의 경우 제외 된 것보다 많은 열이 포함됩니다.

아래의 의견 덕분에 나는 예상을 들여다 보았다. 그리고 이것은 아직도 나에게 이상적인 상황이 아니다. 다음 사용하는 경우 :

var list = session 
    .CreateCriteria(typeof (Task)) 
    .SetProjection(Projections 
         .ProjectionList() 
         .Add(Projections.Property("Id"))) 
    .List(); 

내가 변수 list 단지 인의 int와 끝까지, 나는 기본값으로 설정된 모든 필드 내 전체 작업 개체 만이 선호하는 것입니다. 이것은 가능한가? 지금까지 내가 본 모든 것은 아니오라고 말했습니다.

+0

질문에 대한 답변에서 내 게시물에 대한 업데이트를 참조하십시오. – Danielg

답변

34

예 예상을 사용하여 조건 쿼리를 사용하여이 작업을 수행 할 수 있습니다. 사용할 속성 만 투사하고 컴파일 된 쿼리의 select 절에 포함되는 속성 만 프로젝트에 포함하십시오.

http://nhibernate.info/doc/nh/en/index.html#querycriteria-projection

업데이트

그러나 몇 가지 제한과 함께, 이러한 목표를 달성하는 방법에는 여러 가지가 있습니다 편집 할 수 있습니다. 1) NHibernate 방식.

var list = session.CreateCriteria(typeof (Task)) 
.SetProjection(Projections.ProjectionList() 
        .Add(Projections.Property("Name"), "Name") 
        .Add(Projections.Property("ID"), "ID") 
) 
.SetResultTransformer(Transformers.AliasToBean(typeof (Task))) 
.List(); 

은 단순히 투영 별칭으로 속성 이름을 지정하고 AliasToBean 변압기는 실제 클래스에 그 전망을 매핑합니다. 이 방법의 한계는 매핑하는 모든 속성에 POCO 클래스에 setter가 있어야한다는 것입니다.이 설정은 보호 된 설정 자일 수 있지만 setter가 있어야합니다.

는 또한이 단순히 작업 클래스의 새 인스턴스로 OUPUT있는 인덱스 목록을 매핑하는 LINQ를 사용하는 약간 다른 방식으로

var list = session.CreateCriteria(typeof (Task)) 
.SetProjection(Projections.ProjectionList() 
        .Add(Projections.Property("Name")) 
        .Add(Projections.Property("ID")) 
) 
.List<IList>() 
.Select(l => new Task() {Name = (string) l[0], ID = (Guid) l[1]}); 

에서뿐만 아니라 LINQ와 함께이 작업을 수행 할 수 있습니다. linq가 객체를 채우는 데 사용하는 것이기 때문에 매핑 된 모든 속성에 공용 설정자가 있어야한다는 점만 제외하면 위와 같은 제한이 적용됩니다.

이 정보가 도움이되기를 바랍니다.

+0

원본 질문 –

0

이것이 귀하의 목적에 부합되는지는 확실하지 않지만 단지 제안 일뿐입니다. 질문이 끝나면 항상을 사용하여 SQL보기를 생성 한 다음 보기에 대해 파일을 매핑합니다.

NHibernate는 CRUD 연산이 데이터 무결성 문제와 관련하여 문제가 될지라도 모든 테이블과 마찬가지로 뷰를 처리합니다.

5

당신의 편집에 대한 응답으로 : 내가 아는 한, 이것은 불가능합니다.

그러나, 당신은 무엇을 할 수 있는지, NHibernate에 의해 알려진 클래스를 만드는 것입니다, 그것은 당신이 관심있는 속성이 포함되어 있습니다.

예를 들어

는 'TaskView'클래스는 특정 포함하는 'Task'클래스의 속성.
Hibermate가이 클래스에 대해 알고 있도록 hbm.xml 파일에서 TaskView 클래스를 '가져 오기'해야합니다 (가져 오기 매핑 참조).
그런 다음 투영을 사용하여 'Task'를 TaskView 인스턴스로 변환 할 수 있습니다. NHibernate가 생성하는 쿼리를 살펴보면 TaskView 클래스를 채우는 데 필요한 컬럼 만 검색한다는 것을 알 수 있습니다. 나뿐만 아니라 여기에 게시 것 같은

뭔가 : NHibernate and Collection Counts

+0

에 대한 내 업데이트를 참조하십시오. Nhibernate Screencast 2a의 Summer (원) 포스터가이 정확한 접근 방식 IIRC를 보여줍니다. http://unhandled-exceptions.com/blog/index.php/2008/06/26/summer-of-nhibernate-session-02a-exploring-query-methods-and-syntaxes-cont-screencast-is-available/ –

0

당신이 당신의 기본 생성자 기본 값을 설정하는 설정 시도? 이것은 응용 프로그램 측면에서 문제이므로 해결해야 할 문제가 있습니다. Btw, 왜 각 순열에 대한 생성자가 필요합니까? Hibernate는 모든 인수 생성자 또는 인수 생성자를 사용하고 setter를 사용하므로이 작업을 모두 수행 할 필요가 없습니다. 실제로 올바르게 기억한다면 바이트 코드 조작 마법으로 올바르게 구성하면 설정자가없는 모든 비공개 필드를 설정할 수도 있습니다.

-1

나는 비슷한 질문을했고 NHibernate는 SQL 생성 이후 응용 프로그램이 사용하는 가장 일반적인 기능이 부족한 것 같다. 일부 열만 선택할 수있는 기능. 이것은 정말로 진부합니다. 만약 내가 프로젝트에 참여했다면, 단지 필드를 선택하기 위해 후프와 거꾸로 뛰어 다니는 로직을 거부했을 것입니다. 그것에 대한 답이 있더라도 나는 너무 단순한 연구를하기에는 너무 복잡한 연구를합니다. Nhibernate의 linq 공급자에서 프로젝션을 사용할 수 있음을 알고 있지만 매우 복잡한 쿼리의 경우 특정 필드 만 선택할 수는 없습니다. 그것들 모두 또는 당신은 DTOs/Models를 만들지 않으면 안됩니다. 사용자가 단지 적은 기록을 원하기 때문에 복사하지 않아도되는 원래의 DTO/모델을 만들어야합니다. 정규 SQL 기반 쿼리 (linq 제외)에 대한 제외/포함 목록은 필수 항목입니다. 이 ORM이 가장 기본적인 것들을 먼저 처리하기를 바랍니다. 필드가 데이터베이스의 결과 집합에 반환되지 않으면 모델 작성을 무시하십시오. 누군가가 간단한 해결책/해킹/해결 방법을 줄 수 있기를 바랍니다.

+0

그 생각은 믿을 수 없을 정도로 우아한 해결책이고 내 질문을 완전히 해결합니다. 뉴 햄프셔는이 메커니즘을 제공하고 잘 수행합니다. 이것은 NH 3.0 이전에 원래 더 쉽게되었을 때 요청되었습니다. –

+0

네, 그 영사를 가지고 우아한. 그러나 전체 모델 대신 부분 열을 선택할 수 없다는 것은 원시 SQL 쿼리에 대해 말한 것입니다. http://stackoverflow.com/questions/22889128/select-fields-on-some-tables-and-only-specific-fields-in-other-tables-to-mappe – SamMan

+0

본래의 질문은 기준 쿼리에 관한 것이므로 이상합니다. 구체적으로. 여러 nh (및 몇 가지 다른 가정 재배도 너무) 나는 직접 SQL 쿼리를 사용하지 않는 것이 좋습니다. 최악의 경우 SP를 사용해야하며 SQL과 같은 코드에 SQL을 임베드하는 데 유효한 인수를 본 적이 없습니다. –

관련 문제