【发布时间】:2017-10-20 17:30:37
【问题描述】:
我有一个类似的问题: How to retrieve multiple columns from non-entity type sql query?
我需要实现方法string[,] DirectQuery(string sqlText, string[] param),它基本上是 SQL Server Management Studio 的 C# 等效项。
用户应该以字符串文本的形式输入 SQL 查询(+ 字符串参数以避免 SQL 注入)并接收回包含查询结果的字符串矩阵。
在内部,我使用的是实体框架。
这是我的实现:
public string[,] DirectQuery(string sqlQuery, string[] param)
{
//discover how many fields are specified in the select clause
string ip = sqlQuery.ToLower().Split(new string[] { "from" }, StringSplitOptions.None)[0];
int cols = ip.Count(y => y == ',') + 1;
//execute the query
DbRawSqlQuery<string> res = param != null ? _context.Database.SqlQuery<string>(sqlQuery, param) : _context.Database.SqlQuery<string>(sqlQuery);
//wrap everything in a matrix to return
return res.ToArray().Array2Matrix(res.ToArray().Length /cols, cols);
}
在哪里
public static T[,] Array2Matrix<T>(this T[] flat, int rows, int cols) where T : class
是我将平面数组转换为rows x cols 矩阵的自定义方法。
如果用户在 select 子句中指定了一个属性,那可以正常工作,但如果需要 2+ 个字段,则执行 DirectQuery 会触发运行时异常 dbrawsqlquery he data reader has more than one field. Multiple fields are not valid for EDM primitive or enumeration types。这是完全合理的,但由于查询可以是我无法创建自定义类来包装所有可能结果的任何内容。
你有什么建议?
【问题讨论】:
-
如果您真的希望允许用户输入原始 SQL 查询然后代表他们执行它们,EF 可能不是适合这个。您应该查看像 Dapper.NET(例如,它为该网站提供支持)之类的东西,它可以轻松地执行原始 SQL 并将结果转换为漂亮的 .NET 对象以供使用
-
非常感谢,它运行良好。但是我仍然遇到一些参数问题。用户在他们的查询中指定一定数量的参数,按照他们喜欢的方式命名它们(@p0、@customerId、@foo、...),并在字符串[]中传递它们各自的值。如果我将参数 string[] 直接传递给 Query 方法,Dapper 会触发异常;相反,它需要像
new { p0 = "17R13DT_GP_02_MP2", ... }这样的结构。有没有更紧凑的方法?
标签: c# sql-server entity-framework-6