2013-10-01 4 views
2

학술 논문 테이블이있는 데이터베이스가 있었고, 논문이 "주요"저널에 게재되었는지 여부를 나타내는 열이 있다고 가정 해 보겠습니다. 모든 저자를 나열하는 쿼리와 그 중 하나에 게시 된 적이 있는지 여부를 쿼리 할 수 ​​있습니다. 모양은 다음과 같습니다.Hibernate : CastProjection을위한 서술자가 없다.

select author, max(cast(major_journal as INT)) as ever_published 
from AcademicPapers 
group by author; 

쿨! 지금 나는 NHibernate로 그것을하고 싶다.

No persister for: NHibernate.Criterion.CastProjection 
:이 프로그램을 실행할 때, 나는 어느 정도 이해할 수없는 나에게 예외가, 그러나

Projections.Max<AcademicPaper>( 
    m => Projections.Cast(NHibernateUtil.Int32, Projections.Property("major_journal"))) 
    .WithAlias(() => report.EverPublished) 

: 쿼리의 나머지 부분을 절단하고, max(cast(...)) 부분에 초점이 시도

나는이 프로젝션 비즈니스를 잘못 구성했음을 100 % 확신하지만, NHibernate에 대한 좋은 참조를 아직 찾을 수 없었다. 하나를 검색 할 때마다 StackOverflow가 있습니다. 나는이 특별한 문제가있는 손을 얻고 싶습니다. 또는 실제로 여기에서 벌어지고있는 일들에 대한 적절한 글에 대한 링크를 원합니다.

감사합니다.

+1

즉각적인 문제에 대한 해결책을 찾았습니다. 'Projections.Max'는 여러 번 과부하가 걸립니다. 하나의 과부하는 단순히 또 다른 투영을 할 수 있습니다.이 경우 'Projections.Cast'. 'Projections.Max ( Projections.Cast (NHibernateUtil.Int32, Projections.Property ("major_journal")) .WithAlias ​​(() => report.EverPublished)' 내 원래 : 그래서 필요한 라인이 될 수 있습니다 시도가 불필요하게 복잡한 버전의 'Projections.Max'를 사용하고있었습니다. – phil

답변

0

이 문제를 올바르게 이해했기 때문에이 플래그가 true로 설정된 용지가 하나 이상있는 모든 작성자를 얻고 싶습니다.

왜 Linq를 쓰는 것이 더 쉬운지, 그런 간단한 시나리오에서 작동해야하는 이유는 무엇입니까? 나는 또한 부울에 깃발을지도 것, 그래서 전혀 Max 작업을 할 필요 ... 예이없는 것 같아요 :

var authorsWithPublications = session.Query<Paper>() 
    .Select(p => new { Author = p.Author, HasPublished = p.HasPublished }) 
    .Where(p => p.HasPublished == true).ToList(); 

내가이 간단한 시나리오를 사용, 나를이 아무튼 알고하자

법인 + 매핑 : : 't는 당신의 문제에 맞는 테스트 데이터의

public class Paper 
{ 
    public virtual int Id { get; set; } 
    public virtual string Author { get; set; } 
    public virtual bool HasPublished { get; set; } 
    public virtual string Description { get; set; } 
    public virtual string Something { get; set; } 
    public virtual string SomethingElse { get; set; } 
} 

public class PaperMap : ClassMap<Paper> 
{ 
    public PaperMap() 
    { 
     Id<int>("Id"); 

     Map(p => p.Author); 
     Map(p => p.HasPublished); 
     Map(p => p.Description); 
     Map(p => p.Something); 
     Map(p => p.SomethingElse); 
    } 
} 

생성하고 쿼리를

,363,210
using (var session = sessionFactory.OpenSession()) 
{ 
    Random r1 = new Random(); 

    for (int i = 0; i < 100; i++) 
    { 
     session.Save(new Paper() 
     { 
      Author = "Author" + i, 
      HasPublished = r1.Next(0, 2) == 0 ? false : true, 
      Description = "Description" +i, 
      Something = "Something" + i, 
      SomethingElse = "something else" + i 
     }); 
    } 
    session.Flush(); 

    var authorsWithPublications = session.Query<Paper>() 
       .Select(p => new { Author = p.Author, HasPublished = p.HasPublished }) 
       .Where(p => p.HasPublished == true).ToList(); 
} 

그것은 실제로 정확히 그 저자는 ... 당신이 더 그냥 별개의 결과를 가지고 처리 할 수있는 날을 반환 ...

: 편집 시작 : 이 플래그의 최대 값과 모든 저자를 조회 최대가 아니라고 c.HasPublished는 SQLSERVER에서 비트 필드 인 경우

var authorsWithPublications = session.Query<Paper>() 
       .GroupBy(p => new { Author = p.Author }) 
       .Select(p => new { 
        Author = p.Key, 
        HasPublished = p.Max(c=> c.HasPublished) 
       }) 
       .ToList(); 

그러나 , 그것은 당신에게 SQL 예외를 줄 것이다 : 그것은 LINQ와 약간 까다로운되고, 다음 LINQ 쿼리는 결과를 반환 비트 필드에서 허용됩니다. 이 nHibernate 수에 의해 지원되지 않기 때문에

는 예외 Code supposed to be unreachable가 발생합니다

...HasPublished = p.Max(c => c.HasPublished == true ? 1 : 0) 

같은 LINQ 문 고급형 아파트 int로하는 부울로 변환하는 중 ...

내가 처음 LINQ 쿼리 실행을 얻을 발견하는 유일한 방법은 매핑 내에 수식을 지정하는 것입니다 :

Map(p => p.HasPublished).Formula("cast (HasPublished as int)"); 

이제이 공식은 모든 SELECT 문에 적용됩니다, 문은 다음과 같이 표시됩니다

select paper0_.Author as col_0_0_, max(cast (paper0_.HasPublished as int)) as col_1_0_ 
from [Paper] paper0_ 
group by paper0_.Author 

은 어쨌든 당신은 이미 해결책을 발견하고 다음 실제로 공식

의 필요없이 같은 일
var criteria = session.CreateCriteria<Paper>(); 
criteria.SetProjection(
    Projections.Group<Paper>(p=>p.Author), 
    Projections.Max(
     Projections.Cast(NHibernateUtil.Int32, Projections.Property("HasPublished"))) 
    ); 
var result = criteria.List(); 

아마도 우리 둘 다 뭔가를 배웠습니다.)

+0

내가 찾고있는 것은 조금 다르지만 linq 접근법이 아마 작동 할 것이라는 점은 의심의 여지가 없지만 모든 (고유 한) 저자 및 출판 여부를 나타내는 0 또는 1을 포함합니다. 출판 된 저자와 출판되지 않은 저자를 분리 된 두 개의 쿼리로 분리하라는 요청을받지 않았습니다. 답변 해 주셔서 감사합니다. 오랫동안 그 원래의 의도를 여전히 캡처합니다. 나는 또한 자신을 찾은 해결책으로 원래 질문에 주석을 추가했습니다. 나는 여기에 새로운 브랜드이기 때문에 대답을 제출하지 않습니다.) – phil

+0

답변에 대한 자세한 예제를 정말 고맙게 생각합니다. 다시 한 번 감사드립니다. – phil

+0

@phil 제 답변에 몇 가지 추가 사항을 추가했습니다. 아마도 당신에게도 흥미로울 것입니다. – MichaC