Generics 柴油机的一般用途';s查找或筛选以执行删除

Generics 柴油机的一般用途';s查找或筛选以执行删除,generics,rust,generic-programming,rust-diesel,Generics,Rust,Generic Programming,Rust Diesel,我正在尝试使用通用的Diesel函数来缩减重复性任务,比如根据主键删除一行 我得到的行的一般插入工作相对较快,但删除查询似乎相当困难。我尝试使用find()和filter()来解决这个问题。我也咨询过类似的话题,但没有成功 使用find 使用柴油机::前奏::*; 使用diesel::query\u dsl::methods::FindDsl; 使用std::error::error; 发布结构数据库{ 连接:SQLITE连接, } impl数据库{ 发布fn删除行结果 哪里 T:FindDsl

我正在尝试使用通用的Diesel函数来缩减重复性任务,比如根据主键删除一行

我得到的行的一般插入工作相对较快,但删除查询似乎相当困难。我尝试使用
find()
filter()
来解决这个问题。我也咨询过类似的话题,但没有成功

使用
find
使用柴油机::前奏::*;
使用diesel::query\u dsl::methods::FindDsl;
使用std::error::error;
发布结构数据库{
连接:SQLITE连接,
}
impl数据库{
发布fn删除行结果
哪里
T:FindDsl>::输出:柴油机::可识别,
>::作为柴油机输出::关联::HasTable>::作为柴油机输出的表::查询\u生成器::AsQuery>::查询`

=注意:由于`泛型的'diesel::query_builder::IntoUpdateTarget`的impl上的要求不容易,所以必需。在像diesel这样的高度泛型系统中,泛型更难实现

我更喜欢将步骤分解为非常小的部分,并尽可能避免链接。在这一过程中,您基本上需要为每个步骤添加特征边界。一个很好的方法是为非常复杂的特征边界使用/创建类型别名。并且您可以为您的特殊用途创建自己的类型别名

当我查看生成的错误消息时,我主要查看被调用的函数/方法所描述的类型边界

逐点:

  • 来自
  • 需要
  • 调用
    delete
    的结果类型是a,由
    T::Table
    T::WhereClause
    参数化。这是自定义类型别名
    DeleteFindStatement
  • 来自
  • 使用柴油机::{
    关联::HasTable,
    助手类型::查找,
    查询生成器:{DeleteStatement,IntoUpdateTarget},
    查询\u dsl::方法::ExecuteSL,
    };
    类型DeleteFindStatement=
    删除声明;
    impl数据库{
    pub fn remove_row(&self,table:Tbl,pk:pk)->结果
    哪里
    Tbl:FindDsl,
    Find:IntoUpdateTarget,
    DeleteFindStatement:ExecuteSL,
    {
    设find=table.find(pk);
    让delete=diesel::delete(find);
    删除。执行(&self.conn)?;
    好(())
    }
    }
    
    对于基于
    过滤器的版本,您需要自己尝试它,因为您没有提供足够的代码来说明
    id
    应该是什么;如错误消息所示

    另见:

    即使主键在所有情况下都是
    &str
    ,使其成为通用键是否有好处


    对我来说,使用泛型类型比插入一组泛型生存期参数更容易。

    好的,因此插入cargo errors中提到的特征边界在这里并没有真正的帮助。我基本上理解您在这里所做的事情,但遗憾的是,我没有看到从这些错误消息到您建议的解决方案的可理解的路径,even在执行小步骤时。因此,我想您只需要了解更多有关柴油机如何工作的信息。但是,非常感谢您的帮助!在
    过滤器
    变体中,所有表都有一个主键“id:String”列。这需要如何指定?即使主键在所有情况下都是
    &str
    ,将主键设置为泛型是否有好处?
    use diesel::prelude::*;
    use diesel::query_dsl::methods::FilterDsl;
    use std::error::Error;
    
    pub struct DB {
        conn: SqliteConnection,
    }
    
    impl DB {
        pub fn remove_row<T>(&self, table: T, pk: &str) -> Result<(), Box<Error>>
        where
            T: FilterDsl<bool>,
            <T as FilterDsl<bool>>::Output: diesel::Identifiable,
            <T as FilterDsl<bool>>::Output: diesel::associations::HasTable,
        {
            diesel::delete(table.filter(id.eq(pk))).execute(&self.conn)?;
            Ok(())
        }
    }
    
    use diesel::{
        associations::HasTable,
        helper_types::Find,
        query_builder::{DeleteStatement, IntoUpdateTarget},
        query_dsl::methods::ExecuteDsl,
    };
    
    type DeleteFindStatement<F> =
        DeleteStatement<<F as HasTable>::Table, <F as IntoUpdateTarget>::WhereClause>;
    
    impl DB {
        pub fn remove_row<Tbl, Pk>(&self, table: Tbl, pk: Pk) -> Result<(), Box<Error>>
        where
            Tbl: FindDsl<Pk>,
            Find<Tbl, Pk>: IntoUpdateTarget,
            DeleteFindStatement<Find<Tbl, Pk>>: ExecuteDsl<SqliteConnection>,
        {
            let find = table.find(pk);
            let delete = diesel::delete(find);
            delete.execute(&self.conn)?;
            Ok(())
        }
    }