如何从SQL查询返回动态对象

jmo*_*era 1 c# sql entity-framework dbcontext asp.net-web-api

我有一个storeprocdure返回集合的情况,但我没有如何对象结构,因为查询是非常动态的.

一个查询可以返回:

Id | 位置| MarketSegment | ...... n列

另一个可以回来

Id | 销售代表| 位置| 地区| ...... n列

我只是简单地返回一个"对象",如下面的代码所示.我知道这不会起作用,但我怎么设置它呢?

using (DbContext db = new Context())
{

    var items = db.Database.SqlQuery<object>(
        "SP @Param1, @Param2",
        new SqlParameter("Param1", ped),
        new SqlParameter("Param2", 25)
    ).ToList();

    return Request.CreateResponse<List<object>>(HttpStatusCode.OK, items);
}
Run Code Online (Sandbox Code Playgroud)

编辑:

我不知道是否显示SP会有所帮助,除非我能解释得更多.

每列都表示为自定义字段.用户可以创建n个自定义字段.因此,如果您为User1运行SP并且他有5个自定义字段,则每个自定义字段将在列中表示,但如果User2有3个自定义字段,则仅表示3列.我无法控制的是自定义字段名称和自定义字段数.

LMK*_*LMK 10

如果在 SQL 2016 或更高版本上,请将“FOR JSON AUTO”添加到查询中以返回 JSON,例如:

var json = db.Database.SqlQuery<string>("Select x, y, z FROM tbl FOR JSON AUTO").First();
Run Code Online (Sandbox Code Playgroud)

然后使用 Json.Net 创建动态对象

var myDynamic = JObject.Parse(json)
Run Code Online (Sandbox Code Playgroud)


Yul*_*dra 7

您不能SqlQuery<T>用于自定义字段.

创建将返回给定泛型类型的元素的原始SQL查询.类型可以是具有与查询返回的列的名称匹配的属性的任何类型,也可以是简单的基本类型.- MSDN

但是,你可以ExecuteReader用来实现这一目标.

using (var db = new Context())
{
    db.Database.Connection.Open();

    var cmd = db.Database.Connection.CreateCommand();
    cmd.CommandText = "SP @Param1, @Param2";
    cmd.Parameters.Add(new SqlParameter("Param1", ped));
    cmd.Parameters.Add(new SqlParameter("Param2", 25));

    List<List<object>> items = new List<List<object>>();
    var reader = cmd.ExecuteReader();
    while (reader.Read())
    {
        var item = new List<Object>();
        items.Add(item);

        for (int i = 0; i < reader.FieldCount ; i++)
            item.Add(reader[i]);
    }

    return Request.CreateResponse<List<object>>(HttpStatusCode.OK, items);
}
Run Code Online (Sandbox Code Playgroud)


Ono*_*osa -3

如果您知道可以返回所有可能的列,那么使用具有超出您需要的属性的类就没有问题。

public class Data
{
public int ID {get;set;}
public string SalesRep {get;set;}//Simply will be empty in the first example, but populated in the second.
public string Location {get;set;}
}
Run Code Online (Sandbox Code Playgroud)