Как выполнить следующий SQL-запрос с использованием LINQ или HQL - PullRequest
1 голос
/ 03 июля 2011

Как выполнить следующий запрос, используя Castle ActiveRecords и LINQ или HQL?

SELECT a.id, s.classes, COUNT (p.id), MAX (p.date) ASпоследний, MIN (p.date) AS first
ОТ учетной записи a
LEFT JOIN school s ON s.account_id = a.id
LEFT ПРИСОЕДИНЯЙТЕСЬ к пользователю u ON u.account_id = a.id
LEFTТочки соединения p ON p.user_id = u.id
ГДЕ оплата = "S"
GROUP BY a.id

Таблицы связаны следующим образом: ER-Diagramm

У меня также есть классы ActiveRecord для всех таблиц с определенными правильными отношениями (если я делаю запрос поэтапно, он работает, но он медленный, так как строк много), и я попробовал следующее, которое неработал:

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, Count = points.Count() };

, который выдавал следующее The method or operation is not implemented -Exception at:

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

Ответы [ 2 ]

1 голос
/ 03 июля 2011

Нашел решение с помощью HQL - я все еще открыт для решения LINQ:

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]))
                };
0 голосов
/ 03 июля 2011

Я думаю, что ваш запрос Linq будет выглядеть примерно так:

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()
             };

Хотя я не уверен, насколько хорошо NHibernate будет обрабатывать комбинации group by и Count().Возможно, вы захотите посмотреть, чем в итоге будет сгенерированный SQL, если он не выдаст ошибку.

Если это не сработает, вы можете выбрать записи обратно и сгруппировать / подсчитать их вприложение, а не больше, как:

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);
...