Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这个EF查询可以优化吗?_C#_Entity Framework_Entity Framework 4_Linq To Entities - Fatal编程技术网

C# 这个EF查询可以优化吗?

C# 这个EF查询可以优化吗?,c#,entity-framework,entity-framework-4,linq-to-entities,C#,Entity Framework,Entity Framework 4,Linq To Entities,我不熟悉实体框架,不确定何时使用即时加载和Include,何时使用带有Select的LINQ查询,以及何时根据需要加载实体。我也不知道EF是否以及何时缓存实体。(是的,我最终会阅读文档:-) 我正在ASP.NETMVC网站内部构建一个消息传递系统,性能将非常重要。想象一下下面的场景 当蕾哈娜进入她的收件箱时,她需要看到一个邮件列表,每个邮件都有发件人的姓名和图片。想象一下约翰为他的新歌写了蕾哈娜的歌词。在她的收件箱里,有一条有约翰照片的信息。当约翰走进他的发件箱时,他看到了与蕾哈娜的名字和照片相

我不熟悉实体框架,不确定何时使用即时加载和
Include
,何时使用带有
Select
的LINQ查询,以及何时根据需要加载实体。我也不知道EF是否以及何时缓存实体。(是的,我最终会阅读文档:-)

我正在ASP.NETMVC网站内部构建一个消息传递系统,性能将非常重要。想象一下下面的场景

当蕾哈娜进入她的收件箱时,她需要看到一个邮件列表,每个邮件都有发件人的姓名和图片。想象一下约翰为他的新歌写了蕾哈娜的歌词。在她的收件箱里,有一条有约翰照片的信息。当约翰走进他的发件箱时,他看到了与蕾哈娜的名字和照片相同的信息

因此,当我们从数据库中获取消息时,可能需要发送者和接收者的个人资料图片。想象一下下面的查询:

private static Func<MyEntities, int, Message> _getMessageByIdQuery = CompiledQuery.Compile(
    ( MyEntities ctx, int messageId ) => ctx.Messages
        .Include( "SenderUser" )
        .Include( "SenderUser.UserProfile.Image" )
        .Include( "RecipientUser" )
        .Include( "RecipientUser.UserProfile.Image" )
        .SingleOrDefault( message => message.ID == messageId ) );
private static Func\u getMessageByIdQuery=CompiledQuery.Compile(
(MyEntities ctx,int messageId)=>ctx.Messages
.包括(“发送者”)
.Include(“SenderUser.UserProfile.Image”)
.包括(“接收方用户”)
.Include(“RecipientUser.UserProfile.Image”)
.SingleOrDefault(message=>message.ID==messageId));
这个查询是否有效?考虑到
User.ID
UserProfile.UserID
是一对一的,有没有办法在不加载
SenderUser.UserProfile.Image的情况下加载
SenderUser.UserProfile.Image
?我想我需要使用LINQ JOIN来实现这一点。这是正确的吗

如果只需要一个字段(例如,仅从
UserProfile
加载
ImageID
),使用LINQ避免加载所有字段是否更有效

使用
Load
在代码中的某个地方执行同样的操作是否更好

这样的查询每次都会进入数据库吗?想象一下,我们有一千条信息,都来自同一个人。我们会每次都查询他的
图像吗

我正在使用EF4和ASP.NETMVC3


谢谢。

一种方法是直接从查询发送自定义显示/数据对象,这样您就不需要加载额外的对象。例如:

var dto = ctx.Messages
          .Where(whereclause)
          .Select(m=> new DTOTYPE
                         {Id = m.Id, 
                          Content= m.Content, 
                          SenderId = m.SenderUser.Id, 
                          SenderImage = m.SenderUser.UserProfile.Image, 
                          SenderImageId = m.SenderUser.UserProfile.ImageId}) 
                         //more fields if you need any

这将取决于你的场景,但这样你就不必做疯狂的包括所有。但是您需要管理视图/数据对象,因为对于许多不同的屏幕和视图,它们可能无法控制。希望这有帮助

没有人能告诉您代码的性能,您必须进行基准测试。
是,如果使用联接,则可以避免加载SenderUser。如果您想知道如何查看生成的sql代码,请查看。

使用@AD.Net建议的投影。使用投影时,您可以传输您真正需要的数据,而不是传输包含您从未使用过的特性的整个对象。请注意,每次查询数据库中的消息时,都会加载图片


如果您计划显示来自同一用户的更多消息,请在单独的查询中仅加载图像一次!此外,收件人是否真的需要加载其图像?如果是,为什么不在他登录时只加载一次图像,并将其保存在会话中,而不是为她收件箱中的每封邮件加载相同的数据?

感谢您的回复!想象一下约翰给蕾哈娜发了很多信息。她会收到一个装满他的邮件的收件箱(还有他的照片!),但在列表加载之前,不知道他的照片会重复。所以,先加载邮件,然后在单独的查询中加载所有发件人的图像。否则,您可以接收来自同一用户的100条消息,并将其图像加载100次。谢谢。最后,我尝试了手动
join
s和使用
Select
进行投影,看起来
Select
生成了稍微重一些的连接,但更易于维护,所以我将保持原样。