LINQ What does 'select new' do?
本文关键字:do new select LINQ What does | 更新日期: 2023-09-27 18:11:19
我已经构建了以下LINQ查询
var activeMembers = from m in context.py3_membershipSet
join c in context.ContactSet on m.py3_Member.Id equals c.ContactId
where m.statuscode.Value == 1
orderby m.py3_name
select m;
但是我已经看到了一个格式化的例子:
var contacts =
(
from c in xrm.ContactSet
join a in xrm.AccountSet on c.ParentCustomerId.Id equals a.Id
where a.Name == "Acme Pty Ltd"
select new
{
Name = c.FullName,
DOB = c.BirthDate,
Gender = (c.FormattedValues.Contains("gendercode") ? c.FormattedValues["gendercode"] : "Ambiguous")
}
);
(我意识到这是一组不同的数据)在这种情况下包含"select new"实际上做了什么?
与我在第一个代码块中的例子相比,它的好处是什么?
我知道有些人可能会觉得这是一个乏味的问题,但我想学习LINQ,需要快速学习它。但是我也不想在客户的实时CRM上运行一些我不完全理解的东西
LINQ返回一个匿名对象的集合。select new
让您定义该对象的布局以及该匿名对象中包含的属性/属性名称。
您还可以使用select new ClassName { }
返回您定义的实体类的实例列表。
正如前面的答案所指出的,这两种方法都返回匿名类型。为了完整地回答你的问题:"第二种说法比第一种说法有什么好处?"
第一条语句按原样返回m
的所有字段。如果您有7个"列",那么activeMembers
将包含所有列和它们包含的任何数据。
在第二个语句中,您将结果投射到只有3个字段的自定义匿名对象中。不仅如此,您还可以在将"源字段"存储到匿名对象之前对它们执行逻辑。这为您提供了很大的灵活性,可以将它们存储在容器类中,而无需在代码中定义该类。
你也可以做select new SomeClass { }
,它会把你的结果投影到一个预定义的类容器中。
下面的伪代码可能有助于理解它们的区别,也可能没有帮助:
var myQuery = from p in someContext.someTable
group p by p.someField into g
select new MyContainer {
Field1 = g.Sum(a => a.field1)
Field2 = g.Max(a => a.field2)
};
上面的 myQuery
现在是MyContainer
的集合。如果我省略了MyContainer
类,那么它将是一个包含我指定的字段的匿名类型的集合。显然,这里的区别在于MyContainer
必须在代码的其他地方定义,而匿名类是在编译时为您构建/定义的。:
var myQuery = from p in someContext.someTable
select p;
myQuery
是一个匿名类,包含someTable
中的所有字段及其值。
您正在使用Queryable.Select<TSource, TResult>(IQueryable<TSource>, Expression<Func<TSource, TResult>>)
方法,其中ContactSet是TSource,匿名对象返回类型是result。你的代码也可以写成
...Select(r => new {
Name = c.FullName,
DOB = c.BirthDate,
Gender = (c.FormattedValues.Contains("gendercode") ? c.FormattedValues["gendercode"] : "Ambiguous")
})
,其中select方法返回匿名类型的集合。
另外,由于看起来像是在查询数据库,因此在幕后还发生了一些事情。IQueryable实现查看您编写的Select方法,并将您提供的表达式转换为有效的SQL,以便它可以检索您返回的匿名对象的所有必要信息。注意,我说过IQuerable的实现将提供的表达式(不是函数)转换为sql。Select扩展方法只接受表达式,而不接受函数,因为它不能将函数转换为sql。