Reputation: 327
I just started working with LINQ. How can I use SUM and LEFT JOIN using LINQ. I am trying to build the query below in LINQ. Is it possible?
SELECT t.TenantID, t.TenantFName, t.TenantLName, t.RentalAmount, t.PetRent, t.HousingAmount, t.UtilityCharge, t.TVCharge, t.SecurityDeposit, t.HOAFee,
t.ParkingCharge, t.StorageCharge, t.ConcessionAmount, t.ConcessionReason, t.TenantEmail, t.TenantPhone, t.CellPhoneProviderID, t.MoveInDate,
p.PropertyID, p.PropertyName,
TotalDebit, HousingDebit, TotalCredit, HousingCredit
FROM Tenants t
JOIN Properties p ON t.PropertyID = p.PropertyID
LEFT JOIN (
Select
TenantID,
SUM(CASE WHEN TransactionTypeID = 1 AND ChargeTypeID != 6 AND TenantTransactionDate <= Now() THEN TransactionAmount ELSE 0 END) AS TotalDebit,
SUM(CASE WHEN TransactionTypeID = 1 AND ChargeTypeID = 6 AND TenantTransactionDate <= Now() THEN TransactionAmount ELSE 0 END) AS HousingDebit,
SUM(CASE WHEN TransactionTypeID = 2 AND ChargeTypeID != 6 AND TenantTransactionDate <= Now() THEN TransactionAmount ELSE 0 END) AS TotalCredit,
SUM(CASE WHEN TransactionTypeID = 2 AND ChargeTypeID = 6 AND TenantTransactionDate <= Now() THEN TransactionAmount ELSE 0 END) AS HousingCredit
From TenantTransactions
Group By TenantID
) sums ON sums.TenantID = t.TenantID
Where t.Prospect = 2
AND t.PropertyID = 1
Thanks
Upvotes: 0
Views: 87
Reputation: 34421
I used classes to model you database. See code below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication53
{
class Program
{
static void Main(string[] args)
{
List<Tenants> tenants = new List<Tenants>();
List<Properties> properties = new List<Properties>();
List<TenantTransactions> transactions = new List<TenantTransactions>();
var tenantTransactions = transactions.GroupBy(x => x.TenantID).Select(x => new
{
id = x.Key,
totalDebit = x.Where(y => (y.TransactionTypeID == 1) && (y.ChargeTypeID != 6) && (y.TenantTransactionDate <= DateTime.Now)).Sum(y => y.TransactionAmount),
housingDebit = x.Where(y => (y.TransactionTypeID == 1) && (y.ChargeTypeID == 6) && (y.TenantTransactionDate <= DateTime.Now)).Sum(y => y.TransactionAmount),
totalCredit = x.Where(y => (y.TransactionTypeID == 2) && (y.ChargeTypeID != 6) && (y.TenantTransactionDate <= DateTime.Now)).Sum(y => y.TransactionAmount),
housingCredit = x.Where(y => (y.TransactionTypeID == 2) && (y.ChargeTypeID == 6) && (y.TenantTransactionDate <= DateTime.Now)).Sum(y => y.TransactionAmount)
}).ToList();
var results2 = (from t in tenants
join p in properties on t.PropertyID equals p.PropertyID
join tt in tenantTransactions on t.TenantID equals tt.id into ps
from tt in ps.DefaultIfEmpty()
select new { t = t, p = p, tt = tt })
.Where(x => (x.t.PropertyID == 1) && (x.t.Prospect == 1))
.GroupBy(x => x.t.TenantID)
.Select(x => new {
tenantID = x.Key,
tenantFirstName = x.FirstOrDefault().t.TenantFName,
tenantLastName = x.FirstOrDefault().t.TenantLName,
tenantEmail = x.FirstOrDefault().t.TenantEmail,
tenantPhone = x.FirstOrDefault().t.TenantPhone,
tenantCellPhoneProvider = x.FirstOrDefault().t.CellPhoneProviderID,
properties = x.Select(y => new {
propertyID = y.p.PropertyID,
propertyName = y.p.PropertyName,
rentalAmount = y.t.RentalAmount,
petRent = y.t.PetRent,
houseingAmount = y.t.HousingAmount,
utilityCharge = y.t.UtilityCharge,
tvCharge = y.t.TVCharge,
sercurityDeposit = y.t.SecurityDeposit,
hoaFee = y.t.HousingAmount,
parkingCharge = y.t.ParkingCharge,
storageCharge = y.t.StorageCharge,
concessionAmount = y.t.ConcessionAmount,
concessionReason = y.t.ConcessionReason,
tenantMoveInDate = y.t.MoveInDate
}).ToList(),
totalDebit = x.FirstOrDefault().tt.totalDebit,
housingDebit = x.FirstOrDefault().tt.housingDebit,
totalCredit = x.FirstOrDefault().tt.totalCredit,
housingCredit = x.FirstOrDefault().tt.housingCredit,
}).ToList();
}
}
public class TenantTransactions
{
public int TenantID { get; set; }
public int TransactionTypeID{ get;set;}
public int ChargeTypeID { get;set;}
public DateTime TenantTransactionDate { get;set;}
public decimal TransactionAmount { get;set;}
}
public class Tenants
{
public int PropertyID { get; set; }
public int Prospect { get; set; }
public int TenantID { get; set; }
public string TenantFName { get; set; }
public string TenantLName { get; set; }
public decimal RentalAmount { get; set; }
public decimal PetRent { get; set; }
public decimal HousingAmount { get; set; }
public decimal UtilityCharge { get; set; }
public decimal TVCharge { get; set; }
public decimal SecurityDeposit { get; set; }
public decimal HOAFee { get; set; }
public decimal ParkingCharge { get; set; }
public decimal StorageCharge { get; set; }
public decimal ConcessionAmount { get; set; }
public string ConcessionReason { get; set; }
public string TenantEmail { get; set; }
public string TenantPhone { get; set; }
public string CellPhoneProviderID { get; set; }
public DateTime MoveInDate { get; set; }
}
public class Properties
{
public int PropertyID { get; set; }
public string PropertyName { get; set; }
}
}
Upvotes: 1
Reputation: 545
Roughing out an answer and making a few assumptions about your object model, I'd start off by calculating each of the sums individually with something akin to this statement:
var tenantsTotalDebit = tenantTransactions.Where(tt.TenantId == requestedTenantId && tt.TransactionTypeID == 1 && tt.ChargeTypeID != 6 && tt.TenantTransactionDate <= DateTime.Now).Select(tt => tt.TransactionAmount).Sum();
After you've got all the sums, you can create another query that queries the Tenants
and, assuming the Tenants
object has it's associated Properties
as a member, you could combine them in something like this:
var tenantQuery = tenants.Where(t.Prospect == 1 && t.PropertyID ==1).Select(t.TenantID, t.TenantFName, ..., tenantsTotalDebit, tenantsHousingDebit, tenantsTotalCredit, tenantsHousingCredit);
You can include values beyond the object type that you're querying in a Select()
method, so you can include the precalculated sums after determining them separately.
Upvotes: 1