ОБНОВЛЕНИЕ 8/31/2011
Гийом Лафорж почти сделал это:
http://gaelyk.appspot.com/tutorial/app-engine-shortcuts#query
Похоже, он выполняет преобразование AST, чтобы выполнить:
alias as Entity
немного. Классная штука, Groovy 1.8 + AST transform = LINQ-esque запросы на JVM. Решение GL требует больше работы, насколько я вижу, чтобы реализовать все возможности запросов (например, подзапросы, объединение с использованием (полевого) синтаксиса и т. П.), Но для его проекта Gaelyk, по-видимому, нет необходимости.
EDIT
В качестве обходного пути к достижению чистого синтаксиса LINQ я решил определить псевдонимы. Ничего страшного, и устраняет серьезные препятствия, которые, вероятно, потребуют сложных преобразований AST, чтобы осуществить.
Итак, вместо:
from c as Composite
join t as Teams
...
Теперь я определяю псевдонимы (примечание: необходимо привести к автоматическому заполнению полей):
def(Teams t,Composite c,Schools s) = [Teams.new(),Composite.new(),Schools.new()]
и использовать синтаксис карты для from, join и т. Д.
from c:Composite
join t:Teams
...
Чтобы решить проблему № 2 (см. Оригинал ниже), добавьте методы уровня экземпляра getProperty к каждому псевдониму pogo (область действия которого ограничена закрытием ORM, в котором он вызывается, nice). Мы просто возвращаем имя свойства строки при создании оператора sql.
[t,c,s].each{Object o-> o.metaClass.getProperty = { String k-> k } }
Добиться "хорошего" прогресса; -)
Теперь, чтобы выяснить, что делать с "=", это сложно, так как заданное свойство void. Возможно, придется использовать eq, neq, gt и т. Д., Но на самом деле предпочтительнее литеральные символы, что делает читаемость ближе к sql.
Если интересно, LINQ делает немного закулисного. У Джона Скита (хвала его имени) есть хороший ТАК ответ
Как внутренне работает LINQ?
ORIGINAL
Проверял LINQ, очень впечатлен.
// LINQ example
var games =
from t in Teams
from g in t.Games
where g.gameID = 212
select new { g.gameDate,g.gameTime };
// Seeking Groovy Nirvana
latest { Integer teamID->
from c as Composite
join t as Teams
join s as Schools on ( schoolID = {
from Teams
where t.schoolID = s.schoolID } )
where t.teamID = "$teamID"
select c.location, c.gameType, s.schoolName
group c.gameID
order c.gameDate, c.gameTime
}
Предлагаемая версия Groovy компилируется нормально, и если я определяю псевдонимы c, t, s с соответствующими им POGO, я получаю строго типизированный IDE auocomplete на полях, хорошо. Однако нигде рядом с LINQ, где нет (видимых) определений переменных, кроме самого запроса, полностью самодостаточного и строго типизированного, вау.
Хорошо, так можно ли это сделать в Groovy? Я думаю (надеюсь), да, но я одержим 2 вопроса:
1) Как неявно заполнить переменную псевдонима без определения? В настоящее время я переопределяю asType () для String, поэтому в "from c as Composite" c получает приведение к Composite. Отлично, но IDE "думает", что в области закрытия неопределенный c является строкой и, таким образом, не выполняет автозаполнение полей POGO; - (
2) Поскольку # 1 не решен, я определяю псевдонимы, как указано выше, чтобы я мог получить автозаполнение. Отлично, взломан (по сравнению с LINQ), но делает свое дело. Проблема здесь в том, что в «select c.location, c.gameType ...» я бы хотел, чтобы поля не оценивались, а просто возвращали «c.location» в метод выбора ORM, а не ноль (который является его значение по умолчанию). getProperty () должен работать здесь, но мне нужно, чтобы он применялся только к полям pogo при вызове из области ORM (например, методы, специфичные для поля orm, такие как select, order, group и т. д.). Потерянный бит там, возможно, есть способ аннотировать методы orm, или только вызывать «специальный» pogo getProperty через вызовы методов orm (который является делегатом замыкания в запросе выше нирваны).
Следует отметить, что я не собираюсь создавать всеобъемлющий LINQ для Groovy, но я бы хотел, чтобы это было одно конкретное подмножество LINQ.