EntityFramework LINQ查询返回相同的值

时间:2017-07-06 07:29:56

标签: c# entity-framework linq

帮助理解为什么该查询返回相同的值,但如果我使用匿名类型,则返回正确的结果

axis=0

[{{0}}]

2 个答案:

答案 0 :(得分:2)

  

我做了一些假设:

     
      
  • 我假设您的实体类名为Fromdevicemessage
  •   
  • 我认为MessageString属性
  •   
LINQ中的

.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个对象。因此,结果列表将一个字符串列表

在某些情况下,创建匿名类型很有用。最常见的是,如果要返回多个值(例如MessageRecipient属性),则非常有用。

但是,您的示例仅检索单个属性。在这种情况下,使用匿名类型没有任何好处。当您想要检索单个属性时使用匿名类型会使代码更加复杂,没有充分的理由或好处 您将自己负责以后解开匿名类型并阅读其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