7

我正在查询名为messages;的表中的现有记录。然后将此查询用作“查找或创建”功能的一部分:

fn find_msg_by_uuid<'a>(conn: &PgConnection, msg_uuid: &Uuid) -> Option<Vec<Message>> {
    use schema::messages::dsl::*;
    use diesel::OptionalExtension;

    messages.filter(uuid.eq(msg_uuid))
        .limit(1)
        .load::<Message>(conn)
        .optional().unwrap()
}

我已将此设置为可选,因为在这种情况下,查找记录和查找无记录都是有效的结果,因此该查询可能会返回 a Vecwith oneMessage或 empty Vec,所以我总是最终检查是否Vec为空或不使用像这样的代码:

let extant_messages = find_msg_by_uuid(conn, message_uuid);

if !extant_messages.unwrap().is_empty() { ... }

然后如果它不是空的,则使用以下代码将第一个Message作为Vec我找到的消息

let found_message = find_msg_by_uuid(conn, message_uuid).unwrap()[0];

我总是取第一个元素,Vec因为记录是唯一的,所以查询只会返回 1 或 0 条记录。

这对我来说感觉有点乱,似乎采取了太多步骤,我觉得好像有查询记录那么它不应该返回Option<Message>Option<Vec<Message>>或者None如果没有与查询匹配的记录。

4

1 回答 1

9

如评论中所述,使用first

尝试加载单个记录。Ok(record)如果找到则返回,Err(NotFound)如果没有返回结果。如果查询确实是可选的,您可以调用.optional()它的结果来获取Result<Option<U>>.

fn find_msg_by_uuid<'a>(conn: &PgConnection, msg_uuid: &Uuid) -> Option<Message> {
    use schema::messages::dsl::*;
    use diesel::OptionalExtension;

    messages
        .filter(uuid.eq(msg_uuid))
        .first(conn)
        .optional()
        .unwrap()
}
于 2017-09-19T12:45:22.140 回答