我是一名终于开始理解匿名类型的初学者。
那么在LINQ查询中,您可以在linq查询中形成所需的返回值类型吗?看来这样做的方式是匿名型吗?
有人可以向我解释是否以及何时可以使用Tuple / Expando对象?他们似乎都非常相似?
答案 0 :(得分:4)
在LINQ中通常不使用元组和Expando对象。它们与匿名类型完全不同。
匿名类型通常用于“塑造”LINQ查询;例如,您可以定义具有string Name
属性和int Age
属性的类型。
元组是仅用作“对”或“三元组”类型结构的类型。例如,可以定义Tuple<string, int>
,但属性的名称名为Item1
和Item2
,而不是Name
和Age
。元组通常不用于形成LINQ查询,因为这些属性名称使代码不太清晰。
ExpandoObject完全不同。它允许您在运行时将属性添加到现有对象。
答案 1 :(得分:3)
您没有说明问题的上下文,因此我将回答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()
};
好的,现在已经足够了。