2014-12-29 122 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语句被允许,其他的被忽略。