簡體   English   中英

使用實體框架中的SqlQuery RAW查詢返回匿名類型

[英]Return Anonymous Type using SqlQuery RAW Query in Entity Framework

如何使Entity Framework SqlQuery返回匿名類型。

現在我運行一個context.TheObject.SqlQuery() RAW查詢。 查詢連接兩個表,我想返回連接表的結果。

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

我試過db.Database.SqlQuery<DbResults>("the sql query here") ; 使用與結果對象匹配的預定義類,但所有字段均為null。

使用Entity Framework 6和MySQL。

我在這里走出困境,並試圖解決你的根本問題,而不是直接回答你的問題。

您使用預定義類的方案應該有效 一個可能的缺陷是列名和類的屬性不匹配。

示例代碼(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. 執行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();
            }
        }
  1. 將每行中的各個值讀入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;
            }
  1. 使用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";

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM