2

我正在使用 Exposed 库在 Kotlin 中使用旧版 MySQL 数据库。我已经让它在 MySQL 上运行良好(简单查询按预期工作)。我正在运行 MySQL 版本 5.7.26,但我认为问题与 MySQL 本身无关。

我有两张桌子,events 和 event_years。events 中的相关列是 id(int,主键)和 name(varchar 255)。Event_years 包含一个 id(int,主键)、year(日期时间)和 event_id(int,外键),以及与此问题无关的其他内容。

一个事件在 event_years 中可能有零行或多行引用它。我想选择事件名称和年份,并按年份对结果进行排序。

我能够使用 mysql CLI 来实现这一点,如下所示:

SELECT e.id, e.name, y.id, y.date 
FROM events e, event_years y
WHERE e.id = y.event_id
ORDER BY y.date;

在 Kotlin 中,我为 Events 和 EventYears 创建了对象:

object Events : Table("events") {
    val id = integer("id").autoIncrement().primaryKey()
    val name = varchar("name", length = 255)
}

object EventYears : Table("event_years") {
    val id = integer("id").autoIncrement().primaryKey()
    val eventId = integer("event_id").uniqueIndex()
    val date = date("date")
}

然后我尝试了以下查询:

val res = EventYears.innerJoin(Events)
    .slice(Events.name, Events.id, EventYears.date, EventYears.id)
    .select { EventYears.eventId eq Events.id }
    .groupBy(EventYears.date)

我希望结果是一个包含这些值的 Iterable 对象(就像我在没有加入的情况下进行查询时收到的那样),但是引发了一个异常:

java.lang.IllegalStateException: Cannot join with foo.bar.Events@b307e119 as there is no matching primary key/ foreign key pair and constraint missing

预先感谢您的任何帮助。我现在已经两次阅读 Exposed 文档,但仍然无法理解为什么这不起作用。

4

2 回答 2

1

您应该定义您的eventIdasval eventId = reference("film", Events).uniqueIndex()然后您就可以毫无例外地使用您的查询。

另一种方法是在innerJoin

val res = EventYears.innerJoin(Events, {EventYears.eventId}, {Events.id})
    .slice(Events.name, Events.id, EventYears.date, EventYears.id)
    .selectAll()
    .groupBy(EventYears.date)
于 2019-07-17T15:21:20.803 回答
0

尝试指定约束:

val joinResult = Events.join(EventYears, JoinType.INNER, additionalConstraint = {
EventYears.eventId eq Events.id

然后选择如下

joinResult.select({ EventYears.eventId eq Events.id }) {
   val eventId = it[Events.id]
   val eventYearsId = it[EventYears.eventId]
}
于 2019-07-16T05:34:28.393 回答