首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >匿名类型和用户定义类型的LINQ select查询

匿名类型和用户定义类型的LINQ select查询
EN

Stack Overflow用户
提问于 2015-09-08 14:22:21
回答 3查看 17.5K关注 0票数 16

匿名类在c#中具有只读属性。它通常用于在linq select查询中声明,以便从数据库中获取特定值。在我的代码中,我使用query.The语句选择匿名类的新对象时遇到了下面这样的问题。我有一个StudentClerkshipsLogModel的模型类。当我使用模型名时,查询结果允许编辑。

代码语言:javascript
复制
var query = (from entity in _tblStudentClerkshipsLog.GetQueryable()
             where entity.StudentID == intStudentID                             
             select new StudentClerkshipsLogModel
             {
                 StudentClerkshipID = entity.StudentClerkshipID,
                 StudentID = entity.StudentID,
                 ClerkshipID = entity.ClerkshipID,
             }).ToList();

当我在select语句中没有提到new后面的类型时,我无法退出。编译器引发错误。匿名对象是只读的。

代码语言:javascript
复制
var query = (from entity in _tblStudentClerkshipsLog.GetQueryable()
             where entity.StudentID == intStudentID                             
             select new 
             {
                 StudentClerkshipID = entity.StudentClerkshipID,
                 StudentID = entity.StudentID,
                 ClerkshipID = entity.ClerkshipID,
             }).ToList()

我的问题是linq如何以不同的方式绑定about two查询。两个查询都有动态绑定,或者第一个是静态的。

感谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-09-08 15:12:08

如果我没理解错的话,你想知道LINQ提供者如何设置匿名对象的属性,因为它们是“真正的”只读属性(没有任何private set,只有get )?

当您为IQueryable<T>调用Select扩展方法时,它接受Expression<Func<T, TResult>类型的表达式。如果您要为Select编写一些存根,您可以使用调试器查看生成的表达式:

代码语言:javascript
复制
public static class MyExtensions
{
    public static void MySelect<T, TResult>(this IQueryable<T> query, Expression<Func<T, TResult>> projection)
    {
        System.Diagnostics.Debug.WriteLine(projection);
    }
}

不同之处在于编译器如何为命名类型和匿名类型生成lambda表达式。当您为命名类型调用Select时,表达式将如下所示:

代码语言:javascript
复制
{_ => new Person() {Id = _.Id, Name = _.Name}}

也就是说,首先将构造新的Person对象,然后初始化成员(MemberInit表达式)。

但是当你为匿名类型调用Select时,表达式将被构建为构造函数调用(New表达式):

代码语言:javascript
复制
{_ => new <>f__AnonymousType0`2(a = _.Id, b = _.Name)}

LINQ provider在实现查询结果时将这些lambda编译为委托,最终只是调用匿名类型的构造函数。

票数 11
EN

Stack Overflow用户

发布于 2015-09-08 14:39:12

你得到的错误与LINQ没有任何关系。你可以在不使用LINQ的情况下看到同样的事情:

代码语言:javascript
复制
var anonymous = new { Name = "Fred" };
anonymous.Name = "Joe"; // Error, as properties of anonymous types are read-only

所以如果你想修改你的LINQ查询获取的对象,你不应该使用匿名类型。但这两个LINQ查询都是静态绑定的-匿名类型在编译时仍然是完全已知的,并且编译器对它们应用常规类型限制。例如:

代码语言:javascript
复制
var anonymous = new { Name = "Fred" };
Console.WriteLine(anonymous.Foo); // Error: no property Foo
int bar = anonymous.Name; // Error: no conversion from string to int
票数 17
EN

Stack Overflow用户

发布于 2015-09-08 15:18:01

我在LINQ结果的匿名类型结果中发现了以下差异。

  1. 结果不可编辑,例如,如果我们为网格视图赋值,它将是只读的。匿名object.we作用域的
  2. 问题无法将该类型传递给另一个方法。定义一个var类型的参数;var后面必须始终跟一个初始化表达式。

如果您仅在当前上下文中需要结果用于只读目的,请使用匿名查询。如果你需要其他函数的结果,你必须定义对象的类型。new之后的对象类型将用您想要从result define中获得的属性创建,然后在花括号{}中。不需要初始化model类的所有值。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32450582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档