如何让Entity Framework SqlQuery返回匿名类型。
现在我运行context.TheObject.SqlQuery()
RAW查询。查询连接两个表,我想返回连接表的结果。
如果我将其与context.TheObject.SqlQuery()
类型一起使用,我只能看到相同类型的表的结果。
我试过db.Database.SqlQuery<DbResults>("the sql query here")
;使用与结果对象匹配的预定义类,但所有字段都为空。
将实体框架6与MySQL结合使用。
答案 0 :(得分:9)
我在这里走出困境,并试图解决你的根本问题,而不是直接回答你的问题。
使用预定义类的方案应该可以正常工作。可能存在的缺陷是列名和类的属性不匹配。
示例代码(LinqPad)
var results = Database.SqlQuery<TestResult>("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 :(得分:2)
这就是我的所作所为。
- 执行sp并将结果输入数据读取器
醇>
public static async Task<IEnumerable<object>> 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();
}
}
- 将每行中的各个值读入expando对象,并将expando对象列表放入数组
醇>
public static List<object> ToObjectList(this IDataReader dataReader, bool ignoreUnmappedColumns = true)
{
var list = new List<object>();
while (dataReader.Read())
{
IEnumerable<string> columnsName = dataReader.GetColumnNames();//A custom method implemented below
var obj = new ExpandoObject() as IDictionary<string, object>;
foreach (var columnName in columnsName)
{
obj.Add(columnName, dataReader[columnName]);
}
var expando = (ExpandoObject)obj;
list.Add(expando);
}
return list;
}
- 使用reader.GetSchemaTable()方法获取列列表
醇>
public static IEnumerable<string> GetColumnNames(this IDataReader reader)
{
var schemaTable = reader.GetSchemaTable();
return schemaTable == null
? Enumerable.Empty<string>()
: schemaTable.Rows.OfType<DataRow>().Select(row => row["ColumnName"].ToString());
}
用法
var results =
await
StandaloneFunctions.GetAnonymousResults(_unitOfWork, "spFind",
outputParameters,parameters);
在我的情况下,我碰巧使用SP但这应该适用于查询。您所要做的就是用以下命令替换命令(并删除所有参数传递)
command.CommandType = CommandType.Text;
command.CommandText = "select * from SomeTable";