1

我有以下数据库:

在此处输入图像描述

  1. 表消息:

    • 负责存储发送的消息做不同的电子邮件地址。
  2. 表电子邮件:

    • 只负责存储电子邮件地址(主键 = 电子邮件)(toEmail 与表电子邮件有关系)(Sotres Foo@gmail.com、Foo2@gmail.com 等...)
  3. 表联系人:

    • 用于存储用户的联系人。(商店马克、约翰、汤姆等……)
  4. 表联系人电子邮件

    • 需要此表,因为一个联系人可能有多个电子邮件地址。(存储在表 Emails 中找到的 id)

无论如何这里是一个问题: 我想创建一个查询,它将选择在特定日期发送的所有消息。如果存在,我想在查询中包含联系人姓名。我已经创建了以下查询,但速度很慢:

Func<string, Contact> tryGetContact = (email)=>{
    var contactEmail = db.ContactEmails.FirstOrDefault(x=>x.IdEmail==email);
    if(contactEmail==null)
       return null;
    return contactEmail.Contact; // navigational property created by entity framework.
};

var query = from msg in db.Messages
            join email in db.Emails on msg.ToEmail equals email.Email
            where msg.Date < "some date" && msg.Date > "some other date" 
            select new
            {
                MessageSubject = msg.Subject,
                ToEmail = email.Email,
                Contact = tryGetContact(email.Email) // this slows down the query!
            };

为了使我的查询执行得更快,我是否需要将所有联系人存储在字典中并将此查询分成 2 个查询?

将所有联系人存储在字典中将使事情变得更加高效。但是从数据库中检索我不需要大部分联系人的所有联系人让我觉得我在浪费资源。

4

1 回答 1

3

如果我们可以看到您的 Linq 查询生成的实际 SQL,则更容易确定是什么降低了查询速度。但是,我想这可能与您的tryGetContactFunc 有关,它与查询的主要部分不共享相同的上下文。

所以如果我是对的,每次你调用tryGetContact(email.Email)一个新的完整查询时都会因为这一行而执行:

var contactEmail = db.ContactEmails.FirstOrDefault(x=>x.IdEmail==email);

在这种情况下,db.ContactEmails它不是 SQL 查询中连接的一部分,因此每次都会重新执行。

所以我要做的是添加另一个join以包含ContactEmails在 Linq(和后续 SQL)查询中。这应该是这样的:

var query = from msg in db.Messages
            join email in db.Emails on msg.ToEmail equals email.Email
            join contactEmail in db.ContactEmails on contactEmail.IdEmail equals email.Email
            where msg.Date < "some date" && msg.Date > "some other date" 
            select new
            {
                MessageSubject = msg.Subject,
                ToEmail = email.Email,
                Contact = (contactEmail==null) ? contactEmail.Contact : null,
            };

如果这不起作用,您可能希望db.ContactEmails对所有调用只执行一次,tryGetContact并将结果存储在 Collection(或 HashSet 以获得更好的性能)中。

于 2016-10-25T01:23:20.477 回答