[英]LinqPad dynamic sql and displaying results
我正在使用LinqPad執行一些動態sql,當我調用.Dump()時它返回IEnumerable。 我希望它顯示其返回的匿名類型的結果。 任何幫助在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);
你正在使用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)
所以我為取得結果所做的就是這樣,但我認為必須有更好的方法。
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();
}
除了Joe的回答 :
因為
ExecuteQueryDynamic
,所以使用Linq-to-SQL連接很重要
在實體框架中 不可用 。
以下是如何在LinqPad 5中將不同的數據類型作為參數(基於Northwind數據庫)處理:
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} ...
對於first,second,third,...參數如下:
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語句,忽略其他SELECT語句。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.