2014-12-29 117 views
2

我正在使用LinqPad來執行一些動態sql,並且它在我調用.Dump()時返回IEnumerable。我希望它顯示它返回的匿名類型的結果。感謝您在LinqPad中執行動態sql語句並顯示結果的任何幫助。LinqPad動態sql和顯示結果

這裏是什麼,我試圖做一個代碼片段:

// Any sql string for example. 
var query = "SELECT DISTINCT [CustomerId] FROM Customers Where CustomerId = 2"; 

var dyn = this.ExecuteQuery<dynamic>(query); 

LINQPad.Extensions.Dump(dyn); 
+0

查看答案https://stackoverflow.com/questions/4117713/nice-examples-of-using-net-4-dynamic-keyword-with-linq – sgmoore

回答

1

所以我做了什麼得到的結果是這樣的,但我認爲必須有一個更好的辦法。

using (SqlConnection connection = new SqlConnection(this.Connection.ConnectionString)) 
{ 
    connection.Open(); 

    SqlCommand command = new SqlCommand(query, connection); 
    SqlDataReader reader = command.ExecuteReader(); 

    reader.Cast<IDataRecord>().AsQueryable().Dump();  
} 
2

您在IDataRecord的正確軌道上。爲了使輸出動態,使用DynamicObject:

static class Extensions 
{ 
    public static IEnumerable<dynamic> ExecuteSQL (this DataContext dc, string sql) 
    { 
     var cx = new SqlConnection (dc.Connection.ConnectionString); 
     cx.Open(); 
     return new SqlCommand (sql, cx).ExecuteReader (CommandBehavior.CloseConnection).Cast<IDataRecord>().Select (r => new DynamicDataRecord (r)); 
    } 
} 

class DynamicDataRecord : System.Dynamic.DynamicObject 
{ 
    readonly IDataRecord _row; 
    public DynamicDataRecord (IDataRecord row) { _row = row; } 

    public override bool TryConvert (System.Dynamic.ConvertBinder binder, out object result) 
    { 
     if (binder.Type == typeof (IDataRecord)) 
     { 
      result = _row; 
      return true; 
     } 
     return base.TryConvert (binder, out result); 
    } 

    public override bool TryInvokeMember (System.Dynamic.InvokeMemberBinder binder, object [] args, out object result) 
    { 
     if (binder.Name == "Dump") 
     { 
      if (args.Length == 0) 
       _row.Dump(); 
      else if (args.Length == 1 && args [0] is int) 
       _row.Dump ((int)args [0]); 
      else if (args.Length == 1 && args [0] is string) 
       _row.Dump ((string)args [0]); 
      else if (args.Length == 2) 
       _row.Dump (args [0] as string, args [1] as int?); 
      else 
       _row.Dump(); 
      result = _row; 
      return true; 
     } 
     return base.TryInvokeMember (binder, args, out result); 
    } 

    public override bool TryGetMember (System.Dynamic.GetMemberBinder binder, out object result) 
    { 
     result = _row [binder.Name]; 
     if (result is DBNull) result = null; 
     return true; 
    } 

    public override bool TryGetIndex (System.Dynamic.GetIndexBinder binder, object [] indexes, out object result) 
    { 
     if (indexes.Length == 1) 
     { 
      result = _row [int.Parse (indexes [0].ToString())]; 
      return true; 
     } 
     return base.TryGetIndex (binder, indexes, out result); 
    } 

    public override IEnumerable<string> GetDynamicMemberNames() 
    { 
     return Enumerable.Range (0, _row.FieldCount).Select (i => _row.GetName (i)); 
    } 
} 

這將允許以下內容:

this.ExecuteSQL ("select * from customer").GroupBy (c => c.Name).Dump(); 

編輯:此功能現已作爲v4.53.02內LINQPad。現在你可以去:

ExecuteQueryDynamic ("SELECT DISTINCT * FROM Customer WHERE ID = {0}", 2) 
+0

我跑我的V4「檢查更新」。 51.03版本和LINQPad報告沒有任何更新。 v4.53.02更新何時會通過? – Enigmativity

0

除了Joe's answer

重要的是,您使用的是LINQ到SQL連接,因爲ExecuteQueryDynamic
不可實體框架中。

這裏是如何在LinqPad 5處理不同的數據類型作爲參數(基於羅斯文數據庫):

void Main() 
{ 
    // Boolean 
    ExecuteQueryDynamic(@"DECLARE @Discontinued bit={0}; 
         SELECT DISTINCT * FROM Products 
         WHERE Discontinued = @Discontinued", true).Dump(); 
    // Int 
    ExecuteQueryDynamic(@"DECLARE @OrderId Int={0}; 
         SELECT DISTINCT OrderId, CustomerId, ShipName FROM Orders 
         WHERE OrderID = @OrderId", 10248).Dump(); 
    // String 
    ExecuteQueryDynamic(@"DECLARE @CustomerId nvarchar(max)={0}; 
         SELECT DISTINCT * FROM Customers 
         WHERE CustomerId = @CustomerId", "VINET").Dump(); 
} 

我建議你使用你的SQL一個DECLARE聲明變量。這樣,您可以首先在T-SQL(或LinqPad SQL模式)中嘗試使用指定的固定值 - 如果數據類型不匹配,您將收到有意義的錯誤消息,則可以將其插入ExecuteQueryDynamic並插入{0}, {1}, {2} ...第一,第二,第三,...參數如下:

ExecuteQueryDynamic(@"DECLARE @Discontinued bit={0}; DECLARE @ProductID Int={1}; 
          DECLARE @CategoryID Int={2}; 
          SELECT DISTINCT * FROM Products 
          WHERE Discontinued = @Discontinued AND ProductId = @ProductID 
          AND CategoryID = @CategoryID;      
         ", true, 5, 2).Dump(); 

注: ExecuteQueryDynamic不支持多個結果。這意味着,只有一個SELECT語句被允許,其他的被忽略。