如何通过LINQ-to-SQL查询返回匿名对象

时间:2017-04-20 16:51:12

标签: c# asp.net-mvc linq asp.net-core asp.net-core-mvc

我正在创建一个允许用户运行SQL SELECT命令的工具,结果将显示在HTML表格中。我正在使用ASP.NET Core MVC并试图避免使用SqlConnection / SqlCommand / etc。如果可能的话,直接进入DataContext

例如,如果有人输入

"SELECT Id, Name FROM Table"

,结果是

Id | Name
------------
1  | 'Bob'
2  | 'Harry'

我希望Json(results)成为

[
   { Id: 1, Name: "Bob" },
   { Id: 2, Name: "Harry"}
]

我认为结果的类型为IEnumerable<object>

我现在拥有的是我的存储库中的方法,如

    public List<object> RunQuery(string query)
    {
        using(MyDbContext context = new MyDbContext())
        {
            return context.MiscTable.FromSql<object>(query).ToList();
        }
    }

然后我得到一个像

这样的例外
  

$ exception {System.InvalidOperationException:'FromSql'操作的结果中没有所需的列'SomeColumn'。

其中SomeColumnMiscTable上的某列。显然,我只能使用FromSql查询特定的表。有办法做我想做的事吗?

2 个答案:

答案 0 :(得分:1)

您无法将.FromSql与ad-hoc模型一起使用。查询返回的字段必须与模型完全匹配(没有丢失的字段)。

EF Core尚不支持Ad-hoc /非实体模型,但在路线图中。

https://github.com/aspnet/EntityFramework/wiki/Roadmap

  

非模型类型的原始SQL查询允许使用原始SQL查询来填充不属于模型的类型(通常用于非规范化视图模型数据)。

也无法返回匿名类,因为它们的类型只能在编译类型中知道。您应该为数据库中的实体创建模型(通常每个表有1个模型,但您也可以通过继承在一个表中创建更多模型)。这就是ORM的用途。

如果您只想要原始查询,请直接使用ADO.NET。 ORM用于将表映射到类/对象。

答案 1 :(得分:0)

我相信您可以使用.Include()向FromSql操作的dbset添加其他表。查看此链接以获取示例和其他背景信息。

https://docs.microsoft.com/en-us/ef/core/querying/raw-sql#composing-with-linq

从您的示例中,您的查询可能如下所示:

return context.MiscTable.Include(t => t.RelatedTable).FromSql<object>(query).ToList();

免责声明:我实际上并没有尝试过,所以我不确定它是否真的有效。但这似乎是合理的。