Reputation: 367
I have two queries taking data from a single table with lambda and I would like to use something like a SQL 'join on' method in order to join the tables on a single id. The queries are:
var tbl_emails_received =
db.EmailAddresses
.GroupBy(x => new { x.RecepientID })
.Select(x => new
{
x.Key.RecepientID,
EmailsRecieved = x.Count()
});
and
var tbl_emails_sent =
db.EmailAddresses
.GroupBy(x => new { x.SenderID })
.Select(x => new
{
x.Key.SenderID,
EmailsSent = x.Count()
});
I am trying to replicate what this MsSQL Query is doing. I tried looking at Microsoft's documentation for join
(linked here) but it requires new classes to hold the objects.
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
But it could be that LINQ or C# cannot create objects on the fly like with SQL does with the data. My question is, is there a way I can replicate what the SQL query is doing in LINQ or simple C#? Are there any best practices for this kind of queries? Is there another package I could use that could potentially make this simpler?
Upvotes: 0
Views: 1798
Reputation: 5550
You could try something like this (using your two initial queries)
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();
This has not been tested or fully checked. The only trip to the database is the creation of query
. There is only one class which is the one that is equivalent to the output from your SQL SELECT
statement. (And it has to go somewhere). Or, you could also make that an anonymous class.
Upvotes: 1
Reputation: 890
run select query on db.EmailAddresses .ToList() to get all records from table, now run group by for recipientId , SenderId on top of this query. This way database hit is once only
Upvotes: 1