代码之家  ›  专栏  ›  技术社区  ›  Rei Miyasaka

在Linq中使用.NET 4动态关键字的好例子?

  •  17
  • Rei Miyasaka  · 技术社区  · 14 年前

    所以我刚收到亚马逊的推荐信 LINQ to Objects Using C# 4.0: Using and Extending LINQ to Objects and Parallel LINQ (PLINQ) .

    它说这本书介绍了使用 dynamic

    你能用它做什么 否则你不能用Linq做的关键字?

    3 回复  |  直到 14 年前
        1
  •  21
  •   Joe Albahari    14 年前

    这里有一个想法:通过将LINQ与dynamic结合起来,您可以查询非类型化的数据集,就像它们是类型化的一样。

    例如,假设myDataSet是一个非类型化的数据集。使用动态类型和名为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 of dynamic,这使它适合于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);
        }
      }
    }
    

        2
  •  4
  •   Matt    6 年前

    乔的回答很酷。我知道如何简化用法。如果将此添加到扩展类中:

    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();      
    }
    

    N、 B.:

    • 添加 System.Data.OleDb System.Data 程序集到查询属性
    • 添加 System.Dynamic

    • uq.Connection 只有通过“连接”下拉列表关联了数据库时才可用。如果您选择了 "<none>" ,将发生编译错误。


    更新: ExecuteQueryDynamic latest Beta v4.53.03 of LinqPad ,可用于实现此目的,例如:

    void Main()
    {
        var q=this.ExecuteQueryDynamic("select * from Customers");
        q.Dump();
    }
    

    这将返回 Customers 来自Northwind数据库的表 IEnumerable<dynamic> ,使用Linq2Sql连接。

        3
  •  0
  •   SRSonnenwald    10 年前

     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();      
    }