Linq like predicate to sql string

Posted

技术标签:

【中文标题】Linq like predicate to sql string【英文标题】: 【发布时间】:2021-12-09 14:25:53 【问题描述】:

我想创建一个函数,它应该根据模型和模型的属性类型接受类似 linq 的表达式,并返回一个 SQL 字符串。

public class MyModel

    public int Year  get; set; 

    public string UserName  get; set; 


public static class MyControlClass

    public static string BuildSQL<TModel>(Func<TModel, bool> whereExpression)
    
        return $"SELECT * FROM nameof(TModel) WHERE whereExpression";
    


public main()
    string sqlQuery = MyControlClass.BuildSQL<MyModel>(m => m.Year == 2021 && UserName == "Tester");
    
    //What I wish sqlQuery to be
    //SELECT * FROM MyModel WHERE Year = 2021 AND UserName = "Tester"

任何想法如何做到这一点?我知道 POCO 和其他 ORM 库,我已经尝试和搜索了超过 3 天。我只是找不到解决方案。

【问题讨论】:

您尝试过实体框架吗?一切尽在其中。 如果你的数据库支持 linq-to-sql 你不应该自己构建你的 sql。 @PalleDue 我想知道如何制作不应该或“不应该”的东西 @HenkvanBoeijen 你有没有提到的框架的例子可以在我的案例中使用并获得预期的结果? 好吧,换一种说法,@PalleDue 说:您应该让 ORM 为您完成这项工作。如果您知道 ORM 库,这是否意味着您实际上尝试过其中的任何一个? 【参考方案1】:

解决方案一点也不简单。而且你必须处理Expression&lt;Func&lt;TModel, bool&gt;&gt; whereExpression

然后你可以访问这个表达式ExpressionVisitor例如this answer并生成SQL。

或者您可以通过转义字符串、日期等来节省您的时间,安装 linq2db 并直接写:

public class MyModel

    public int Year  get; set; 

    public string UserName  get; set; 


public static void Main()
   
    // create options builder
    var builder = new LinqToDbConnectionOptionsBuilder();

    // configure connection string
    var options = builder.UseSqlServer(connectionString);

    using var db = new DataConnection(options);

    var query = db.GetTable<MyModel>().Where(m => m.Year == 2021 && m.UserName == "Tester");

    // will generate SQL
    var sql = query.InlineParameters().ToString();

    // will return list of items
    var items = query.ToList();

【讨论】:

以上是关于Linq like predicate to sql string的主要内容,如果未能解决你的问题,请参考以下文章

js 模拟扩展 c# 的 linq 表达式 分享 linq to js

为啥 LINQ 中的 LastOrDefault(predicate) 比 FirstOrDefault(predicate) 快

Linq 中的 LIKE 和 OR 等内容

LINQ to Entities 不支持 LINQ 表达式节点类型“Invoke”

使用 (LINQ/Predicate) 将 DataTable 的所有列名放入字符串数组

LINQ to Entities 中的“NOT IN”子句