帮助理解为什么该查询返回相同的值,但如果我使用匿名类型,则返回正确的结果
axis=0
[{{0}}]
答案 0 :(得分:2)
LINQ中的我做了一些假设:
- 我假设您的实体类名为
Fromdevicemessage
- 我认为
Message
是String
属性
.Select()
不会影响检索哪些项目。它仅影响检索到的项目呈现的方式
如果您了解SQL,您将看到SQL中的SELECT
的工作方式完全相同(这就是为什么LINQ方法被故意称为Select
,因为它的工作方式相同,从功能上讲)
如果您理解每种方法的用意,我会对此有所帮助:
var deviceMessageList1 =_deviceMessageRepository.Fromdevicemessages
.Where(m => m.DeviceId == deviceId) //Only return the items which have their DevicedId set to [deviceId]
.Take(1000) //Give me the first 1000 items
.ToList() //Make a list from these 1000 items
请注意,您只指定了要检索的哪些行。您尚未指定输出格式化的方式。
默认情况下,您将收到相应实体类型Fromdevicemessage
的对象。
您最后看到的列表是List<Fromdevicemessage>
。
var deviceMessageList1 =_deviceMessageRepository.Fromdevicemessages
.Where(m => m.DeviceId == deviceId) //Only return the items which have their DevicedId set to [deviceId]
.Take(1000) //Give me the first 1000 items
.Select(x => x.Message) //For each retrieved item, instead of the item itself, only give me its Message (= string)
.ToList() //Make a list from these 1000 strings
注意Select语句添加的内容。它基本上告诉您不需要完整的Fromdevicemessage
对象,但只需要Message
属性。您基本上告诉编译器:
对于当前检索的每个
Fromdevicemessage
对象,请将其呈现为Message
属性。
您最初使用的是Fromdevicemessage
个对象的集合。但是.Select()
语句将该集合转换为String
个对象的集合。
简化后,Select()
方法会根据您的映射(例如x => x.Message
)转换源集合中的每个对象,并返回映射值列表。
您最后看到的列表是List<String>
。
如果您没有注意到,我更改了您的Select
声明。
您的版本:
.Select( x => new { Message = x.Message } )
我的版本:
.Select( x => x.Message )
两者都是有效的代码,但它们的工作方式略有不同。
您的版本将检索到的项目转换为匿名对象。因此,结果列表将一个匿名对象列表。
我的版本将检索到的项目转换为String
个对象。因此,结果列表将一个字符串列表。
在某些情况下,创建匿名类型很有用。最常见的是,如果要返回多个值(例如Message
和Recipient
属性),则非常有用。
但是,您的示例仅检索单个属性。在这种情况下,使用匿名类型没有任何好处。当您想要检索单个属性时使用匿名类型会使代码更加复杂,没有充分的理由或好处
您将自己负责以后解开匿名类型并阅读其Message
属性。
直接处理字符串更容易,而不是以匿名类型包装它们。这意味着您需要担心一个较少的包裹层。
仔细查看您链接的图片;您的问题具体是为什么调试值(当您将鼠标悬停在结果上时,就像在图片中一样)是不同的?
您在小弹出窗口中看到的内容(扩展前)基本上是您正在检查的变量的.ToString()
输出。
第一个示例包含List<Fromdevicemessage>
。由于Fromdevicemessage
是您自定义的自定义类(我假设您没有覆盖其.ToString()
方法,因此默认输出将是类的名称,而不是其内容< /强>
这就是它的工作原理。如果您覆盖.ToString()
课程中的Fromdevicemessage
方法,则可以更改它的外观。
public override string ToString()
{
return $"Message : {this.Message}";
}
在第二个示例中,您正在处理List
个匿名类型。匿名类型有一个自定义.ToString()
方法,它已经显示对象的内容而不是它的类名(因为匿名对象没有类名,至少就开发人员而言)
答案 1 :(得分:1)
两个查询都是相同的,但在第二个查询中,您使用的是匿名类型。 第一个查询将返回包含该对象中所有属性的原始对象,第二个查询将返回消息,因为您使用的是匿名类型。
为了更好地理解这就像 //第一次查询
select Top 1000 * from Fromdevicemessages
//第二次查询
select Top 1000 Message from Fromdevicemessages