开发者

How to execute the following SQL-Query using LINQ or HQL

How can I execute the following query using Castle ActiveRecords and LINQ or HQL?

SELECT a.id, s.classes, COUNT(p.id), MAX(p.date) AS last, MIN(p.date) AS first

FROM account a

LEFT JOIN school s ON s.account_id = a.id

LEFT JOIN user u ON u.account_id = a.id

LEFT JOIN points p ON p.user_id = u.id

WHERE payment = "S"

GROUP BY a.id

The tables are related in the following way:

How to execute the following SQL-Query using LINQ or HQL

I also have ActiveRecord classes for all tables with the correct relations defined (if I do the query in steps it works, but it is slow as there are a lot of rows) and I tried the following which didn't worked:

var result = from account in AccountRecord.Queryable
             join s in SchoolRecord.Queryable on account equals s.Account into schools
             from school in schools.DefaultIfEmpty(null)
             join user in UserRecord.Queryable on account equals user.Account
             join p in PointsRecord.Queryable on user equals p.User into points
             where account.PaymentType == "S"
             select new { Account = account, School = school开发者_Python百科, Count = points.Count() };

which threw the following The method or operation is not implemented-Exception at:

NHibernate.Linq.Visitors.QueryModelVisitor.VisitGroupJoinClause(GroupJoinClause groupJoinClause, QueryModel queryModel, Int32 index)


Found the solution using HQL - I'm still open for a LINQ solution:

HqlBasedQuery query = new HqlBasedQuery(typeof(AccountRecord),
    "SELECT a, s, COUNT(p), MIN(p.DateUTC), MAX(p.DateUTC) " +
    "FROM AccountRecord a " +
    "LEFT JOIN a.Schools s " +
    "LEFT JOIN a.Users u " +
    "LEFT JOIN u.Points p " +
    "WHERE a.PaymentType=:payment GROUP BY a.Id");
query.SetParameter("payment", "S");
var result = from object[] row in (ArrayList)ActiveRecordMediator.ExecuteQuery(query)
                select new
                {
                    Account = row[0] as AccountRecord,
                    School = row[1] as SchoolRecord,
                    Count = row[2],
                    First = (new DateTime(1970, 1, 1, 0, 0, 0, 0)).AddSeconds(Convert.ToDouble(row[3])),
                    Last = (new DateTime(1970, 1, 1, 0, 0, 0, 0)).AddSeconds(Convert.ToDouble(row[4]))
                };


I think your Linq query would be something like:

var result = from a in AccountRecord.Queryable
             join s in SchoolRecord.Queryable on a.id equals s.account_id
             join u in UserRecord.Queryable   on a.id equals u.account_id
             join p in PointsRecord.Queryable on u.id equals p.user_id
             where a.payment == "S"
             group by a.id
             select new
             {
               Account = a,
               School = s,
               Count = p.Count()
             };

Though I'm not sure how well NHibernate will handle the group by and Count() combination. You might want to see what the generated SQL ends up being, if it doesn't throw an error.

If that doesn't work, you might want to select the records back, and group/count them in the application instead, more like:

var data = from a in AccountRecord.Queryable
           join s in SchoolRecord.Queryable on a.id equals s.account_id
           join u in UserRecord.Queryable   on a.id equals u.account_id
           join p in PointsRecord.Queryable on u.id equals p.user_id
           where a.payment == "S"
           select new
           {
             Account = a,
             School = s,
             Count = c
           };
var grouped = data.ToList.GroupBy(x => x.Account.Id);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜