Muh*_*sir 16 c# linq anonymous-class dynamic-binding
匿名类在c#中只读取属性.这通常用于在linq select query中声明从数据库中获取特定值.在我的代码中,我有以下查询.让我混淆使用新语句选择匿名类的新对象的事情.我有一个模型类StudentClerkshipsLogModel.当我使用模型名称时,查询结果允许编辑.
var query = (from entity in _tblStudentClerkshipsLog.GetQueryable()
where entity.StudentID == intStudentID
select new StudentClerkshipsLogModel
{
StudentClerkshipID = entity.StudentClerkshipID,
StudentID = entity.StudentID,
ClerkshipID = entity.ClerkshipID,
}).ToList();
Run Code Online (Sandbox Code Playgroud)
当我new在select声明后没有提到类型时我无法退出.编译器引发错误.匿名对象是只读的.
var query = (from entity in _tblStudentClerkshipsLog.GetQueryable()
where entity.StudentID == intStudentID
select new
{
StudentClerkshipID = entity.StudentClerkshipID,
StudentID = entity.StudentID,
ClerkshipID = entity.ClerkshipID,
}).ToList()
Run Code Online (Sandbox Code Playgroud)
我的问题是linq如何以不同方式绑定两个查询.两个查询都有动态绑定,或者第一个是静态的.
谢谢
Jon*_*eet 17
你得到的错误与LINQ没有任何关系.你可以在不使用LINQ的情况下看到同样的事情:
var anonymous = new { Name = "Fred" };
anonymous.Name = "Joe"; // Error, as properties of anonymous types are read-only
Run Code Online (Sandbox Code Playgroud)
因此,如果要修改LINQ查询提取的对象,则不应使用匿名类型.但是两个LINQ查询都是静态绑定的 - 匿名类型在编译时仍然是完全已知的,并且编译器对它们应用常规类型限制.例如:
var anonymous = new { Name = "Fred" };
Console.WriteLine(anonymous.Foo); // Error: no property Foo
int bar = anonymous.Name; // Error: no conversion from string to int
Run Code Online (Sandbox Code Playgroud)
Den*_*nis 11
如果我理解正确,你会想知道,LINQ提供程序如何设置匿名对象的属性,因为它们是"真正的"只读属性(没有private set,但get只有)?
当您调用Select扩展方法时IQueryable<T>,它接受类型的表达式Expression<Func<T, TResult>.如果您要编写一些存根,Select可以使用调试器查看生成的表达式:
public static class MyExtensions
{
public static void MySelect<T, TResult>(this IQueryable<T> query, Expression<Func<T, TResult>> projection)
{
System.Diagnostics.Debug.WriteLine(projection);
}
}
Run Code Online (Sandbox Code Playgroud)
不同之处在于编译器如何为命名类型和匿名类型生成lambda表达式.当您调用Select命名类型时,表达式将如下所示:
{_ => new Person() {Id = _.Id, Name = _.Name}}
Run Code Online (Sandbox Code Playgroud)
也就是说,首先Person将构造新对象,然后初始化成员(MemberInit表达式).
但是当你调用Select匿名类型时,表达式将被构建为构造函数调用(New表达式):
{_ => new <>f__AnonymousType0`2(a = _.Id, b = _.Name)}
Run Code Online (Sandbox Code Playgroud)
LINQ提供程序在实现查询结果时将这些lambda编译为委托,最终只调用匿名类型的构造函数.
| 归档时间: |
|
| 查看次数: |
14653 次 |
| 最近记录: |