使用EF核心时使用IN子句进行原始查询

时间:2018-12-24 17:07:03

标签: c# sql entity-framework asp.net-core

首先,对不起,因为我的英语不好。 而且我在使用EF核心原始查询的查询中遇到问题

SELECT * FROM [Iot.Core].[dbo].[LocaleResources] WHERE [Key] IN ({0})

我想将列表字符串作为参数

var inClause = new List<string>() { "Apple", "Banana", "Cream"};

但是DbContext返回的结果不正确。

dbContext_LocaleResources.FromSql(_querySelectLocaleResourceByKeyAndLanguage, inClause).ToList()

请帮助!谢谢

1 个答案:

答案 0 :(得分:0)

您的inClause数据格式错误,无法替换Placehoder。我想出了一种通过使用RawSqlString来结合使用RawSQL和IN子句的方法。

  List<string> list = new List<string>()
        {
            "Apple",
            "Banana",
            "Cream"
        };
        StringBuilder sb = new StringBuilder();
        list.ForEach((item) =>
        {
            sb.Append("'");
            sb.Append(item);
            sb.Append("'");
            sb.Append(",");
        });
        sb.Remove(sb.Length - 1, 1);//{'Apple','Banana','Cream'}

        RawSqlString raw = new RawSqlString($"select * from Customer where Name in ({sb.ToString()})");
        var result = _context.Customers.FromSql(raw).ToList();

更新:

如果您要将字符串列表传递给IN,它将始终发出警告。

  

传递给'FromSql'的SQL表达式嵌入不会被参数化的数据。审查潜在的SQL注入漏洞

一种解决方法是使用Or而不是IN

List<string> list = new List<string>()
        {
            "Apple",
            "Banana",
            "Cream"
        };
        StringBuilder sb = new StringBuilder();
        sb.Append("select * from Customer where "); 
        list.ForEach((item) =>
        {
            sb.Append("Name='");
            sb.Append(item);
            sb.Append("' Or ");
        });
        sb.Remove(sb.Length - 4, 4);
        RawSqlString sql= new RawSqlString(sb.ToString());
        var result = _context.Customers.FromSql(sql).ToList();