所以我剛剛從亞馬遜LINQ to Objects Using C# 4.0: Using and Extending LINQ to Objects and Parallel LINQ (PLINQ)得到了一個建議。Linq使用.NET 4動態關鍵字的好例子?
它說,這本書介紹了使用dynamic
關鍵字使用LINQ,這讓我想:
,你可以用dynamic
關鍵字,你不能使用LINQ做,否則做什麼迷死人?
所以我剛剛從亞馬遜LINQ to Objects Using C# 4.0: Using and Extending LINQ to Objects and Parallel LINQ (PLINQ)得到了一個建議。Linq使用.NET 4動態關鍵字的好例子?
它說,這本書介紹了使用dynamic
關鍵字使用LINQ,這讓我想:
,你可以用dynamic
關鍵字,你不能使用LINQ做,否則做什麼迷死人?
下面是一個想法:通過將LINQ與動態相結合,您可以查詢無類型數據集,就好像它們是鍵入的一樣。
例如,假設myDataSet是一個無類型的DataSet。有了動態打字和)稱爲AsDynamic(一個擴展方法,以下是可能的:
var query = from cust in myDataSet.Tables[0].AsDynamic()
where cust.LastName.StartsWith ("A")
orderby cust.LastName, cust.FirstName
select new { cust.ID, cust.LastName, cust.FirstName, cust.BirthDate };
以下是如何定義AsDynamic擴展方法。注意它返回的動態IEnumerable的,這使得它適用於LINQ查詢:
public static class Extensions
{
public static IEnumerable<dynamic> AsDynamic (this DataTable dt)
{
foreach (DataRow row in dt.Rows) yield return row.AsDynamic();
}
public static dynamic AsDynamic (this DataRow row)
{
return new DynamicDataRow (row);
}
class DynamicDataRow : DynamicObject
{
DataRow _row;
public DynamicDataRow (DataRow row) { _row = row; }
public override bool TryGetMember (GetMemberBinder binder, out object result)
{
result = _row[binder.Name];
return true;
}
public override bool TrySetMember (SetMemberBinder binder, object value)
{
_row[binder.Name] = value;
return true;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return _row.Table.Columns.Cast<DataColumn>().Select (dc => dc.ColumnName);
}
}
}
通過繼承DynamicObject,這需要定製的優勢結合 - 在這裏你接手解決自己成員名稱的過程。在這種情況下,我們綁定get和set成員訪問來檢索或存儲底層DataRow中的對象。
Awsome!當我看到這一點時,我有想法添加.ExecuteSql擴展方法,它允許直接使用LinqPad與SQL服務器連接。 [檢查出來...](http://stackoverflow.com/a/24885293/1016343) – Matt 2014-07-22 11:12:41
儘管我已經習慣了它,現在感覺很自然,在我這個純粹主義者,這讓我相信'AsDynamic'應該被理想地命名爲「ToDynamic」。 「To」意味着身份更改轉換,而「As」本身意味着保留轉換的表示,就像關鍵字一樣。但無論如何,.NET有許多類似的'As's,比如'AsReadOnly'。 – nawfal 2015-08-01 09:24:03
喬的回答很酷。我有一個想法如何簡化使用。如果您添加到擴展類:
public static class Extensions
{
public static IEnumerable<dynamic> ExecuteSql(this UserQuery uq, string sql)
{
var connStr="Provider=SQLOLEDB.1;"+uq.Connection.ConnectionString;
OleDbConnection connection = new OleDbConnection(connStr);
DataSet myDataSet = new DataSet();
connection.Open();
OleDbDataAdapter DBAdapter = new OleDbDataAdapter();
DBAdapter.SelectCommand = new OleDbCommand(sql, connection);
DBAdapter.Fill(myDataSet);
var result = myDataSet.Tables[0].AsDynamic();
return result;
}
}
它允許使用這樣的查詢中LINQPad:
void Main()
{
var query1 = from cust in this.ExecuteSql("SELECT * from Customers")
where cust.ContactName.StartsWith ("C")
orderby cust.ContactName
select new { cust.CustomerID, cust.ContactName, cust.City };
query1.Dump();
}
NB: 您需要添加下列引用:
System.Data.OleDb
從System.Data
裝配到查詢性能System.Dynamic
到查詢性能更新: 我注意到,喬又增加了一個功能ExecuteQueryDynamic
在latest Beta v4.53.03 of LinqPad,可用於實現這一目標,例如:
void Main()
{
var q=this.ExecuteQueryDynamic("select * from Customers");
q.Dump();
}
這將返回Customers
表從Northwind數據庫爲IEnumerable<dynamic>
,使用Linq2Sql連接。
我所做的事情讓我的結果是這樣,但我會認爲有更好的辦法。
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();
}
如果我做一個動態對象LINQ查詢,我得到'錯誤CS1979:在源類型查詢表達式「動態」或類型「動態」的加入順序並不allowed':S。 – 2010-11-07 14:03:55
稍微閱讀一下當前使用動態LINQ的限制以及解決它們的一些方法:http://weblogs.asp.net/davidfowler/archive/2010/08/04/dynamic-linq-a-little- more-dynamic.aspx – egoodberry 2010-11-07 14:42:11