使用 LINQ 或其他模块在 C# 中连接两个查询的结果

Posted

技术标签:

【中文标题】使用 LINQ 或其他模块在 C# 中连接两个查询的结果【英文标题】:Joining results from two queries in C# using LINQ or other module 【发布时间】:2019-11-01 07:39:44 【问题描述】:

我有两个使用 lambda 从单个表中获取数据的查询,我想使用类似 SQL 的“join on”方法来连接单个 id 上的表。查询是:

    var tbl_emails_received =
        db.EmailAddresses
        .GroupBy(x => new  x.RecepientID )
        .Select(x => new
        
            x.Key.RecepientID,
            EmailsRecieved = x.Count()

        );

        var tbl_emails_sent =
        db.EmailAddresses
        .GroupBy(x => new  x.SenderID )
        .Select(x => new
        
            x.Key.SenderID,
            EmailsSent = x.Count()
        );

我正在尝试复制此 MsSQL 查询正在执行的操作。我尝试查看 Microsoft 的 join (linked here) 文档,但它需要新的类来保存对象。

WITH 
tbl_emails_received AS
    (
        SELECT RecepientID, count(FileID) AS EmailsRecieved 
        FROM tbl_ex_EmailAddresses
        GROUP BY RecepientID
    ),
tbl_emails_sent AS
    (
        SELECT SenderId, count(FileID) AS EmailsSent
        FROM tbl_ex_EmailAddresses
        GROUP BY SenderID
    )

SELECT s.SenderID as Id, r.EmailsRecieved, s.EmailsSent, 
    r.EmailsRecieved + s.EmailsSent as TotalEmails,
    slist.EmailAddress, slist.EmailName, slist.DomainName
FROM tbl_emails_received r
    JOIN tbl_emails_sent s
        ON r.RecepientID = s.SenderID

但可能是 LINQ 或 C# 无法像 SQL 处理数据那样动态创建对象。我的问题是,有没有一种方法可以复制 SQL 查询在 LINQ 或简单的 C# 中所做的事情?这种查询有什么最佳实践吗?是否有其他我可以使用的包可以使这更简单?

【问题讨论】:

这可能有帮助。 ***.com/questions/2767709/… 由于这两个 LINQ 查询在此阶段未执行并且使用匿名类型,因此将它们加入到返回所需结果的类型中。 我想知道你的数据模型是否正确。我不明白 EmailAddress 需要发件人和收件人 ID 做什么。我觉得一个更好的数据模型会让你更容易获得你需要的信息。如果您希望在这方面有所改进,请考虑在Code Review 上发布一个新问题,也许 @GertArnold 我同意。 dataModel 有点误导,但它已经使用了一段时间,因此如果不对数据库和 .NET 项目进行大规模更改,就很难修复它。 EmailAddressID 实际上代表一封从 Sender 发送到 Receiver 的电子邮件。 【参考方案1】:

您可以尝试这样的事情(使用您的两个初始查询)

var query = (from er in tbl_emails_received 
            join es in tbl_emails_sent on er.RecepientID equals es.SenderID
            select new emailsReceieved = er, emailsSent = es
            ).ToList();
EMailClass finalClass = query.select(
            x => new EMailClass
            
            Id = x.emailsSent.SenderID,
            EmailsReceived = x.emailsReceieved.EmailsRecieved
            ...
            ).ToList();

这尚未经过测试或完全检查。唯一的数据库之旅是创建query。只有一个类相当于 SQL SELECT 语句的输出。 (它必须去某个地方)。或者,您也可以将其设为匿名类。

【讨论】:

【参考方案2】:

在 db.EmailAddresses .ToList() 上运行选择查询以从表中获取所有记录,现在在此查询的顶部运行 group by for recipientId 和 SenderId。这种方式数据库命中只有一次

【讨论】:

以上是关于使用 LINQ 或其他模块在 C# 中连接两个查询的结果的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中使用组和连接进行 LINQ 查询

如何在 C# 中使用 LINQ 应用右外连接?

如何和我将“或”运算符引入 linq 查询连接

C# linq 多表in语句查询

LINQ 查询在 C# 中使用实体框架获取单列和单行值而不使用 Where

如何使用基于 SQL Query 的连接在 C# 中编写 LINQ?