Groovy 1.8 :: LINQ 已应用
Posted
技术标签:
【中文标题】Groovy 1.8 :: LINQ 已应用【英文标题】:Groovy 1.8 :: LINQ Applied 【发布时间】:2011-06-06 13:53:15 【问题描述】:2011 年 8 月 31 日更新 Guillaume Laforge 几乎做到了:http://gaelyk.appspot.com/tutorial/app-engine-shortcuts#query
看起来他正在做一个 AST 转换来完成:
alias as Entity
位。很酷的东西,Groovy 1.8 + AST 转换 = JVM 上的 LINQ 式查询。就我所见,GL 的解决方案需要更多的工作来实现完整的查询功能(如子查询、使用(字段)语法等),但对于他的 Gaelyk 项目来说显然没有必要。
编辑
作为实现纯 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 等使用 map 语法。
from c:Composite
join t:Teams
...
要解决问题 #2(见下文),将实例级别的 getProperty 方法添加到每个 pogo 别名(其范围仅限于调用它的 ORM 闭包,很好)。我们只是在构建 sql 语句时返回字符串属性名称。
[t,c,s].eachObject o-> o.metaClass.getProperty = String k-> k
取得“良好”进展;-)
现在要弄清楚如何处理“=”,这很棘手,因为 set 属性是无效的。可能必须使用 eq、neq、gt 等,但更喜欢文字符号,以便更接近 sql 的可读性。
如果有兴趣,LINQ 在幕后做了很多工作。 Jon Skeet(赞美他的名字)有一个很好的回复: How LINQ works internally?
原创
一直在检查 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 自动完成,很好。但是,在 LINQ 附近,除了查询本身之外没有(可见的)变量定义,完全独立且强类型,哇。
好的,那么它可以在 Groovy 中完成吗?我认为(希望)是的,但我对 2 个问题感到困惑:
1) 如何在不定义的情况下隐式填充别名变量?目前,我在 String 上覆盖 asType(),因此在“从 c 作为 Composite”中,c 被强制转换为 Composite。很好,但是 IDE “认为” 在闭包范围内 undefined c 是一个字符串,因此 POGO 字段上没有自动完成;-(
2) 由于#1 没有解决,我按照上面的方法定义别名,这样我就可以自动完成了。很好,被黑了(与 LINQ 相比),但可以解决问题。这里的问题是,在“select c.location, c.gameType ...”中,我希望这些字段不被评估,而只是将“c.location”返回给 ORM select 方法,而不是 null(这是它的默认值)。 getProperty() 应该在这里工作,但我需要它仅适用于从 ORM 范围调用时的 pogo 字段(例如,orm 字段特定的方法,如 select、order、group 等)。有点迷失了,也许有一种方法可以注释 orm 方法,或者只通过 orm 方法调用调用“特殊” pogo getProperty(这是上述必杀技查询中的闭包委托)。
应该指出,我不希望为 Groovy 创建一个全面的 LINQ,但我希望看到这个特定的 LINQ 子集发生。
【问题讨论】:
【参考方案1】:Guillaume 使用 AST 转换的最大原因之一是“=”的问题。即使您在 Groovy 中通常使用 == 进行比较,从为其调用的 compareTo 方法中,您也无法区分 ==、!=、=、 之间的区别。在正在讨论的 Groovy 的更高版本中,有两种可能的路径。一种是对每个比较使用不同的方法,另一种是存储可以在运行时访问的最小 AST。这朝着 C# 的方向发展,是一个非常强大的工具。问题更多是关于如何有效地做到这一点。
【讨论】:
Groovy 2.0 + 一些风味的 LINQ 将是一个令人难以置信的组合,Jochen。你们在推动 Groovy 方面做得很好。如果静态 Groovy(又名 Grumpy)不仅仅是谣言,我也会非常有兴趣尝试一下;-)以上是关于Groovy 1.8 :: LINQ 已应用的主要内容,如果未能解决你的问题,请参考以下文章
在Java Spring Boot应用程序中引发ClassNotFoundException的Groovy文件