简体   繁体   中英

C# Entity Framework text SQL query wrapper

I have a problem similar to this: How to retrieve multiple columns from non-entity type sql query?

I need to implement the method string[,] DirectQuery(string sqlText, string[] param) which is basically a C# equivalent of SQL Server Management Studio.

The user is supposed to enter a SQL query as string text (+ string parameters to avoid SQL injection) and receive back a string matrix containing the outcome of the query.

Internally, I'm using Entity Framework.

Here's my implementation:

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);
    }

where

public static T[,] Array2Matrix<T>(this T[] flat, int rows, int cols) where T : class

is my custom method that turns flat arrays into rows x cols matrices.

If in the select clause users specify a single attribute, that works fine, but in case of 2+ fields needed the execution of DirectQuery fires the runtime exception dbrawsqlquery he data reader has more than one field. Multiple fields are not valid for EDM primitive or enumeration types dbrawsqlquery he data reader has more than one field. Multiple fields are not valid for EDM primitive or enumeration types . That's completely reasonable, but since the query can be whatever I can't create a custom class to wrap every possible outcome.

What do you suggest?

The problem is that you're using a method - DbRawSqlQuery which must be told what type to expect, and you're telling it to expect just a string, so it has no idea what to do with more than one returned column.

Maybe it would work if you specified string[] or IEnumerable<string> or something? Alternatively you could define a series of objects with 1, 2, 3, 4 etc values and detect the number of items at runtime and use the correct class... but that seems absurd.

Really though, I'd suggest NOT using EF as someone suggested above. Find something which can return dynmamic objects, OR just use ADO.Net directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM