所以我刚刚从亚马逊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