You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Linq2db结合泛型获取任意数据表中的记录

解决方案:Linq2db 泛型根据表名获取单条记录

你的代码存在几个关键问题,我会逐一修正并给出可行实现:

问题分析

  1. db.GetTable<>() 语法错误,Linq2db 的 GetTable 方法必须指定泛型参数 T;
  2. 泛型 T 未加约束,编译器无法识别 p.ID 属性,会直接编译失败;
  3. ref T obj 的设计冗余,直接返回 T 实例更符合C#编码习惯;
  4. 若实体类与数据库表名不一致,TableName(tbl) 需正确关联,但前提是 T 已配置对应表的映射(Linq2db依赖实体映射生成SQL)。

修正后的代码实现

1. 基础泛型实现(实体与表已映射)

先定义一个包含ID属性的接口,让所有实体类实现它,以此约束泛型T:

public interface IHasId
{
    int ID { get; }
}

// 你的实体类需要实现这个接口并配置表映射,示例:
// [Table("UserTable")]
// public class User : IHasId { public int ID { get; set; } }

public T ObjectGetById<T>(int id) where T : class, IHasId, new()
{
    // 若实体类名称和表名不一致,这里指定表名;一致则可省略TableName
    string tbl = typeof(T).Name;
    using (var db = new cwDB("city5"))
    {
        return db.GetTable<T>()
                 .TableName(tbl) // 仅实体名与表名不同时需要
                 .FirstOrDefault(p => p.ID == id);
    }
}

2. 完全动态表名的场景(不依赖实体类名称)

如果需要完全通过传入的表名定位表,可使用Linq2db的非泛型查询方式,同时注意参数化查询的安全性:

public T ObjectGetById<T>(string tableName, int id) where T : class, new()
{
    using (var db = new cwDB("city5"))
    {
        var table = db.GetTable(typeof(T)).TableName(tableName);
        // 用参数化查询避免SQL注入
        var query = table.Where("ID = @id", new DataParameter("id", id)).FirstOrDefault();
        return query as T;
    }
}

关键注意事项

  • Linq2db 依赖实体类与数据库表的映射关系,无论用泛型还是非泛型方法,都需要确保实体类已通过 [Table] 特性或配置文件完成映射;
  • 若不需要动态指定表名,直接使用 db.GetTable<T>() 即可,Linq2db会自动读取实体类的[Table]特性获取表名;
  • 绝对禁止直接拼接SQL参数,必须使用参数化查询避免注入风险。

内容的提问来源于stack exchange,提问作者Konstantin Sch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:35:34