2

我已经构建了以下 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")
    }
);

(我意识到这是一组不同的数据)在这种情况下,包含“选择新”实际上做了什么?

与我在第一个代码块中的示例相比,它有什么好处?

我意识到有些人可能会觉得这是一个乏味的问题,但我想学习 LINQ 并且需要快速学习它。但我也不想在客户实时 CRM 上运行一些我不完全理解的东西

4

3 回答 3

5

无论哪种方式,LINQ 都会返回一组匿名对象。 select new让您定义该对象的布局以及该匿名对象中包含哪些属性/属性名称。

您还可以使用select new ClassName { }返回您定义的实体类的实例列表。

于 2013-04-29T20:10:39.317 回答
4

正如之前的答案所指出的,这两种方法都返回匿名类型。不过,要完全回答您的问题:“第二个陈述比第一个陈述有什么好处?”

第一条语句按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

于 2013-04-29T20:17:33.493 回答
1

您正在使用Queryable.Select<TSource, TResult>(IQueryable<TSource>, Expression<Func<TSource, TResult>>)ContactSet 是 TSource 并且匿名对象返回类型是 TResult 的方法。您的代码也可以写成

...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。

于 2013-04-29T20:14:09.663 回答