2013-02-14 38 views
7

Vì vậy, tôi đã dành vài giờ qua tìm kiếm câu trả lời và dường như tôi không thể tìm thấy bất kỳ điều gì có ý nghĩa.truy vấn nhibernate với sự tham gia phức tạp qua các thực thể không liên quan

public class Game 
{ 
    public virtual Guid ID { get; set; } 
    public virtual ResultStructure Structure { get; set; } 
    public virtual List<Result> Results { get; set; } 
} 

public class Result 
{ 
    public virtual Player Player { get; set; } 
    public virtual int Position { get; set; } 
} 

public class ResultStructure 
{ 
    public virtual Guid ID { get; set; } 
    public virtual List<ResultOutcomes> Outcomes { get; set;} 
} 

public class ResultOutcomes 
{ 
    public virtual int Position { get; set; } 
    public virtual int Points { get; set; } 
} 

public class PlayerSummary 
{ 
    public virtual Player Player { get; set; } 
    public virtual int Points { get; set; } 
} 

Những gì tôi đang cố gắng làm là có được một danh sách các cầu thủ và các điểm họ đã kiếm được qua vô số các trò chơi khác nhau (có nhiều đơn vị trên game có chứa danh sách các trò chơi). Vì vậy, kết quả cuối cùng của truy vấn sẽ là List<PlayerSummary> SQL Tôi đang tìm sẽ giống như thế này:

SELECT p.*, Sum(rs.points) FROM result r 
    JOIN player p on r.playerid = p.id 
    JOIN game g on r.gameid = g.id 
    JOIN resultstructure rs on g.resultstructureid = rs.id 
    JOIN resultoutcomes ro on rs.id = ro.resultstructureid AND ro.position = r.position 

Lưu ý, tôi cũng sẽ cần phải làm một số truy vấn/tổng hợp chống lại các đơn vị cấu trúc đó là lý do nó bao gồm. Tôi đang cố gắng làm điều này với NHibernate, sử dụng công cụ TypeSafe, và kế hoạch của tôi là ứng dụng là cơ sở dữ liệu bất khả tri, vì vậy tôi không thể sử dụng SQL trực tiếp (hiện tại nó đang sử dụng Postgres, nhưng tôi có thể chuyển sang SQL server tại một số điểm).

Tôi không đặc biệt muốn sử dụng công cụ "HQL" nơi bạn sử dụng các chuỗi ma thuật đó, vì vậy tôi đang cố gắng sử dụng LINQ hoặc QueryOver/Query.

Có ai có thể chỉ cho tôi đúng hướng không?

+0

Đây là trường hợp ** chính xác ** nơi bạn nên sử dụng HQL. "Chuỗi ma thuật" không có nghĩa là bạn nghĩ nó có nghĩa là gì. –

+0

Tôi muốn loại nội dung an toàn thực sự, tôi hiểu ish HQL, và tôi đánh giá cao rằng nó có thể sẽ làm những gì tôi cần, nhưng tôi muốn giữ tất cả mọi thứ như nhau, và tôi đang sử dụng truy vấn trong hầu hết các phần. – Martin

+0

@DiegoMijelshon Tôi đã thêm giải pháp của mình, có thể giải thích tại sao tôi nên sử dụng HQL qua giải pháp mà tôi đã đưa ra? – Martin

Trả lời

6

Dường như điều trên có thể xảy ra trong tình huống của tôi vì có mối quan hệ, nó không chỉ trực tiếp.

Bạn có thể sử dụng JoinAlias.

khác biệt cơ bản là sử dụng JoinAlias, bạn có thể tham gia nhiều bảng vào cùng một bảng cơ sở, trong đó như với JoinQueryOver nó cần tiến trình tuyến tính thông qua các bảng chỉ nối từng bảng.

để truy vấn trông như thế này.

Result resultAlias = null; 
ResultOutcome outcomeAlias = null; 
ResultStructure structureAlias = null; 

var results = Session.QueryOver(() => resultAlias) // Assigns resultAlias so it can be used further in the query. 
    .Inner.JoinQueryOver(x => x.Game) // returns a QueryOver Game so you can do a where on the game object, or join further up the chain. 
    .Inner.JoinAlias(x => x.ResultStructure,() => structureAlias) // joins on the Structure table but returns the QueryOver for the Game, not the structure. 
    .Inner.JoinAlias(() => structureAlias.Outcomes,() => outcomeAlias) // same again for the outcomes 
    .Where(() => resultAlias.Position == outcomeAlias.Position) 
    .Select(
     Projections.Group(() => resultAlias.Player), 
     Projections.Sum(() => outcomeAlias.Points) 
    ); 

Điều đó sẽ cung cấp cho mọi người ý tưởng. Nhược điểm của điều này là hạn chế về "Vị trí" không xảy ra trên Tham gia, mà là trong mệnh đề Where. Tôi rất vui khi được nghe từ bất cứ ai có một tùy chọn để làm điều đó vì điều này sẽ buộc lập kế hoạch truy vấn cơ sở dữ liệu xuống một tuyến đường cụ thể.

Vẫn đang làm việc với các phép biến đổi và thứ tự, nhưng điều đó đã giúp tôi tiếp tục nhiều hơn nữa.

+1

Vì đó là tất cả các kết nối bên trong, nó không quan trọng nơi mà các tiêu chí tham gia thêm được đặt ... phải không? – dotjoe

+0

cũng như họ không phải tất cả tham gia vào "Kết quả", nó không quan trọng từ một quan điểm mã hóa. Các JoinAlias ​​có thể không quan trọng, bạn không thể đặt ResultAlructure JoinAlias ​​trước JoinQueryOver vì nó sẽ cố gắng tham gia chống lại Result thay vì Game. – Martin

Các vấn đề liên quan