代码之家  ›  专栏  ›  技术社区  ›  punkouter

元组与匿名类型与Expando对象。(关于LINQ查询)

  •  4
  • punkouter  · 技术社区  · 15 年前

    我是一个初学者,最终开始了解匿名类型。

    (见旧帖子) What is the return type for a anonymous linq query select? What is the best way to send this data back? )

    所以在LINQ查询中,您要在LINQ查询中形成所需的返回值类型,对吗?这样做的方式似乎是匿名的,对吗?

    有人能给我解释一下我是否可以在何时使用tuple/expando对象吗?他们看起来都很相似?

    2 回复  |  直到 15 年前
        1
  •  3
  •   Amy B    15 年前

    您没有说明您的问题的上下文,所以我将同时回答LinqToObjects和LinqToSQL。

    在LinqtoObjects中,假设您有一个 List<Customer> source .

      //Straight projection.
      //no new instances are created when query is evaluated.
    IEnumerable<Customer> result =
      from c in source where c.Name == "Bob"
      select c;
    
      //Different Type projection
      //a new instance of CustomerName is created
      // for each element in the result when the query is evaluated.
    IEnumerable<CustomerName> result =
      from c in source where c.Name == "Bob"
      select new CustomerName() {Name = c.Name};
    
      //Anonymous Type Projection    
      //a new instance of an anonymous type is created
      // for each element in the result when the query is evaluated.
      //You don't have access to the type's name
      // since the compiler names the type,
      // so you must use var to talk about the type of the result.
    var result =
      from c in source where c.Name == "Bob"
      select new {Name = "Bob"};
    
      //Tuple Projection (same as Different Type Projection)
      //a new instance of Tuple is created
      // for each element in the result when the query is evaluated.
    IEnumerable<Tuple<string, int>> result = 
      from c in source where c.Name == "Bob"
      select new Tuple<string, int>(){First = c.Name, Second = c.Id};
    

    在LinqToSQL中,假设您有一个 IQueryable<Customer> db.Customers

      //Straight projection
      //when the query is resolved
      // DataContext.Translate<Customer> is called
      // which converts the private dbReader into new Customer instances.
    IQueryable<Customer> result =
      from c in db.Customers where c.Name == "Bob"
      select c;
    
      //Different Type Projection
      //when the query is resolved
      // DataContext.Translate<CustomerName> is called
      // which converts the private dbReader into new CustomerName instances.
      // 0 Customer instances are created.
    IQueryable<Customer> result =
      from c in db.Customers where c.Name == "Bob"
      select new CustomerName() {Name = c.Name};
    
      //Different Type Projection with a twist
      //when the query is resolved
      // DataContext.Translate<CustomerGroup> is called
      // which converts the private dbReader into new CustomerGroup instances.
      // 0 Customer instances are created.
      //the anonymous type is used in the query translation
      // yet no instances of the anonymous type are created.
    IQueryable<Customer> result =
      from c in db.Customers
      group c by new {c.Name, TheCount = c.Orders.Count()} into g
      select new CustomerGroup()
      {
        Name = g.Key.Name,
        OrderCount = g.Key.TheCount,
        NumberInGroup = g.Count()
      };
    

    好吧,现在就够了。

        2
  •  4
  •   Stephen Cleary    15 年前

    tuples和expando对象通常不在linq中使用。它们都与匿名类型截然不同。

    匿名类型通常用于“塑造”LINQ查询;例如,您可以定义具有 string Name 属性与AN int Age 财产。

    元组是仅充当“对”或“三重集”类型结构的类型。例如A Tuple<string, int> 可以定义,但属性的名称是命名的 Item1 Item2 不是 Name Age . 元组通常不用于形成LINQ查询,因为这些属性名使代码不那么清晰。

    Expandoobject完全不同。它允许您在运行时向现有对象添加属性。