使用entity framework中的SqlQuery RAW查询返回匿名类型

如何使Entity Framework SqlQuery返回Anonymous类型。

现在我运行一个context.TheObject.SqlQuery() RAW查询。 查询连接两个表,我想返回连接表的结果。

如果我使用类型context.TheObject.SqlQuery()我只能看到相同类型的表的结果。

我试过db.Database.SqlQuery("the sql query here") ; 使用与结果对象匹配的预定义类,但所有字段均为null。

使用Entity Framework 6和MySQL。

我在这里走出困境,并试图解决你的根本问题,而不是直接回答你的问题。

具有预定义类的场景应该有效 。 一个可能的缺陷是列名和类的属性不匹配。

示例代码(LinqPad)

  var results = Database.SqlQuery("select r.Name, b.BankName from relation r inner join BankAccount b on b.RelationId = r.Id where r.Id = 2"); results.Dump(); } public class TestResult { public string Name { get; set; } public string BankName { get; set; } 

我强烈建议您使用显式类型重新访问有问题的代码。


直接回答你的问题:不,你不能从SqlQuery返回匿名类型。 您可以做的最好的事情是构建动态对象 ,但不幸的是,使用TypeBuilder需要相当多的手动工作。 有关示例,请参见http://www.codeproject.com/Articles/206416/Use-dynamic-type-in​​-Entity-Framework-SqlQuery 。

这就是我做的。

  1. 执行sp并将结果输入数据读取器
 public static async Task> GetAnonymousResults(IUnitOfWork unitOfWork, string spName, SqlParameter[] outParameters, params SqlParameter[] parameters) { //meh, you only need the context here. I happened to use UnitOfWork pattern and hence this. var context = unitOfWork as DbContext; DbCommand command = new SqlCommand(); command.CommandType = CommandType.StoredProcedure; command.CommandText = spName; command.Connection = context.Database.Connection; command.Parameters.AddRange(parameters); //Forget this if you don't have any out parameters command.Parameters.AddRange(outParameters); try { command.Connection.Open(); var reader = await command.ExecuteReaderAsync(); return reader.ToObjectList();//A custom method implemented below } finally { command.Connection.Close(); } } 
  1. 将每行中的各个值读入expando对象,并将expando对象列表放入数组中
  public static List ToObjectList(this IDataReader dataReader, bool ignoreUnmappedColumns = true) { var list = new List(); while (dataReader.Read()) { IEnumerable columnsName = dataReader.GetColumnNames();//A custom method implemented below var obj = new ExpandoObject() as IDictionary; foreach (var columnName in columnsName) { obj.Add(columnName, dataReader[columnName]); } var expando = (ExpandoObject)obj; list.Add(expando); } return list; } 
  1. 使用reader.GetSchemaTable()方法获取列的列表
  public static IEnumerable GetColumnNames(this IDataReader reader) { var schemaTable = reader.GetSchemaTable(); return schemaTable == null ? Enumerable.Empty() : schemaTable.Rows.OfType().Select(row => row["ColumnName"].ToString()); } 

用法

  var results = await StandaloneFunctions.GetAnonymousResults(_unitOfWork, "spFind", outputParameters,parameters); 

在我的情况下,我碰巧使用SP但这应该适用于查询。 您所要做的就是用以下代码替换命令(并删除所有参数传递)

 command.CommandType = CommandType.Text; command.CommandText = "select * from SomeTable";