c# - 连接不包含任何关系的表

标签 c# entity-framework linq

我有以下数据库:

enter image description here

  1. 表格消息:

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

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

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

    • 需要此表,因为一个联系人可能有多个电子邮件地址。 (存储在表电子邮件中找到的 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 个查询?

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

最佳答案

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

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

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

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

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

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,
            };

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

关于c# - 连接不包含任何关系的表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40229765/

相关文章:

c# - Entity Framework 。依赖角色有多个具有不同值的主体

c# - 将 Linq 查询结果转换为接口(interface)

c# - 如何将 Div id 作为参数传递给 C# 函数?

entity-framework - Entity Framework 性能问题,saveChanges非常慢

c# - 如何在 IEnumerable<T> 上实现 ICollection<T>

c# - 存储过程不返回列问题

c# - OrderBy().ThenBy().ThenBy() 未在实体列表上给出预期结果

c# - 链接 LINQ 查询时速度缓慢

c# - 调整旋转方面的正确方法

c# - EF 6 System.Data.Objects.ObjectContext 错误