Linq:How to make this easy with one line code? - c#

Forget most learnt about linq,now need to review what is it. And how it works.now I need help for this. Please help me .Thank you so much.
var everyMonthMoneySum = new EveryMonthMoneySum()
{
M_01 = (from o in temp.Where(o => o.IsSign == (short) OrderStateEnum.Success && o.SignMonth == 1)
select o.Signmoney).Sum(),
M_02 = (from o in temp.Where(o => o.IsSign == (short) OrderStateEnum.Success && o.SignMonth == 2)
select o.Signmoney).Sum(),
M_03 = (from o in temp.Where(o => o.IsSign == (short) OrderStateEnum.Success && o.SignMonth == 3)
select o.Signmoney).Sum(),
M_04 = (from o in temp.Where(o => o.IsSign == (short) OrderStateEnum.Success && o.SignMonth == 4)
select o.Signmoney).Sum(),
M_05 = (from o in temp.Where(o => o.IsSign == (short) OrderStateEnum.Success && o.SignMonth == 5)
select o.Signmoney).Sum()+5,
...........................
M_11 = (from o in temp.Where(o => o.IsSign == (short) OrderStateEnum.Success && o.SignMonth == 11)
select o.Signmoney).Sum(),
M_12 = (from o in temp.Where(o => o.IsSign == (short) OrderStateEnum.Success && o.SignMonth == 12)
select o.Signmoney).Sum()
};

It sounds to me like you could do with a dictionary:
var results = temp.Where(o => o.IsSign == (short) OrderStateEnum.Success)
.GroupBy(o => o.SignMonth)
.ToDictionary(g => g.Key, g => g.Sum(o => o.SignMoney));
Note that that won't populate the dictionary with entries for "missing" months.
That will give you a single collection, instead of 12 different variables. Personally I find that's usually a better approach, but we don't really know what you're trying to do with those 12 values...
If you want to make sure the dictionary is populated, I would personally do that with an extra loop afterwards:
for (int i = 1; i <= 12; i++)
{
if (!results.ContainsKey(i))
{
results[i] = 0m;
}
}
It's not "clever", but it works. Alternatively, you could populate an array from the dictionary:
var array = new decimal[13]; // 0 to 12 *inclusive*
foreach (var entry in array)
{
array[entry.Key] = entry.Value;
}
There are other ways of doing it all in the LINQ statement, but I don't know how they'd play with whatever LINQ provider you're using (we don't know) and they're more complex.

Use GroupBy and Where to filter out the values and then group by SignMonth like:
var query = temp.Where(o => o.IsSign == (short) OrderStateEnum.Success)
.GroupBy(r => r.SignMonth)
.Select(grp => new
{
Month = grp.Key,
Sum = grp.Sum(t => t.Signmoney)
});

Related

How to use Exist sql function in Linq

var _query = _dbContext.CashVoucherDetails
.Where(x => x.CreationDate.Date >= From.Date && x.CreationDate.Date <= To.Date && (x.Type == Common.TransactionType.CPV || x.Type == Common.TransactionType.BPV) && x.CompanyCode == BranchCode && x.DebitAmount > 0)
.GroupBy(v => new { v.AccountCode})
.Select(g => new
{
AccountCode = g.Key.AccountCode,
});
var balances = _dbContext.CashVoucherDetails
.Where(x => x.CreationDate.Date <= To.Date && x.CompanyCode == BranchCode)
//.Exist(_query.Account) (I want only account which exist in upper query)
.GroupBy(v => new { v.AccountCode})
.Select(g => new
{
AccountCode = g.Key.AccountCode,
Balance = g.Sum(x => x.DebitAmount - x.CreditAmount),
});
I want to use something like EXIST here in first query I have some specific accounts and in 2nd query I want to calculate balances of those accounts.
Can you please tell how I can use Exist function in LINQ.
Thank you.
I want this query to be implemented in LINQ:
SELECT `c`.`AccountCode`, `c`.`CompanyCode` AS `LocationCode`, COALESCE(SUM(`c`.`DebitAmount` - `c`.`CreditAmount`), 0) AS `Balance`
FROM `CashVoucherDetails` AS `c`
WHERE (CONVERT(`c`.`CreationDate`, date) <= '2022-12-20') AND (`c`.`CompanyCode` = '002') and `c`.`AccountCode` IN
(
SELECT `c`.`AccountCode`
FROM `CashVoucherDetails` AS `c`
WHERE ((((CONVERT(`c`.`CreationDate`, date) >= '2022-12-20') AND (CONVERT(`c`.`CreationDate`, date) <= '2022-12-20')) AND `c`.`Type` IN ('CPV', 'BPV')) AND (`c`.`CompanyCode` = '002')) AND (`c`.`DebitAmount` > 0)
GROUP BY `c`.`AccountCode`
)
GROUP BY `c`.`AccountCode`, `c`.`CompanyCode`;
you can use Contains or Any.
_dbContext.CashVoucherDetails
.Where(x => x.CreationDate.Date <= To.Date && x.CompanyCode == BranchCode)
.Where(x => _query.Select(q => q.AccountCode).Contains(x.AccountCode))
Or
.Where(x => _query.Any(q => q.AccountCode == x.AccountCode))
Maybe something like that
var balances = _dbContext.CashVoucherDetails
.Where(x => x.CreationDate.Date <= To.Date && x.CompanyCode == BranchCode && _query.Any(q => q.AccountCode == x.AccountCode))
.GroupBy(v => new { v.AccountCode})
.Select(g => new
{
AccountCode = g.Key.AccountCode,
Balance = g.Sum(x => x.DebitAmount - x.CreditAmount),
});

Refining a C# lambda query to access second related field in linq query

OK...making good progress on this, but needing to go a bit further than currently.
I have two related tables, billing_transactions and billing_transaction_accessorial_charge. The second is the many to the first one.
The second table has a type and a charge, I need to know in my query if it has none, one or both of them as well as what the charge amount is.
The types for service_code_id
1 (meaning this delivery is a residential delivery)
2 (meaning it has a dish machine)
A delivery can have both. The charge for that is stored in a field called charge.
I currently have this:
var gridData = (from d in db.billing_transactions
where (d.Id > 954 && d.Id < 958)
select new
{
d.base_amount,
d.Id,
dishmachine = d.billing_transaction_accessorial_charge.Where
(p => p.service_code_id == 2),
residential = d.billing_transaction_accessorial_charge.Where
(p => p.service_code_id == 1),
}
).ToArray();
This returns a count of how many dishmachine or residiental charges there are, but I have not been able to figure out how to get the second field in it.
The database structure for the child table is:
id
service_code_id
billing_transaction_id
amount
anybody have any ideas?
Joe
EDIT: Here is the final code block:
var gridData = (from d in db.billing_transactions
where (d.Id > 954 && d.Id < 958)
select new
{
d.base_amount,
d.Id,
dish_charge = d.billing_transaction_accessorial_charge.Where
(p => p.service_code_id == 2)
.Sum(l => l.amount),
dish_count = d.billing_transaction_accessorial_charge.Where
(p => p.service_code_id == 2),
res_count = d.billing_transaction_accessorial_charge.Where
(p => p.service_code_id == 1),
res_charge = d.billing_transaction_accessorial_charge.Where
(p => p.service_code_id == 1)
.Sum(l => l.amount),
}
).ToArray();
This will Sum the amount, if that is what you want
var gridData = (from d in db.billing_transactions
where (d.Id > 954 && d.Id < 958)
select new
{
d.base_amount,
d.Id,
dishmachine = d.billing_transaction_accessorial_charge
.Where(p => p.service_code_id == 2)
.Sum(x => x.amount),
residential = d.billing_transaction_accessorial_charge
.Where(p => p.service_code_id == 1)
.Sum(x => x.amount),
}).ToArray();

Can my two linq lines of code be combined?

I'm not sure how to do this since I'm only familiar with the basic form or Linq.
Here are my two sets of code:
var qry = from x in CustomersChecks.CustomersChecksList
where x.RoutingNumber == routingnumber &&
x.BankAccountNumber == bankAccountNumber &&
x.Branch > 0 &&
x.AccountNumber > 0
orderby x.Name
select x;
var qry2 = qry.GroupBy(x => new { x.Branch, x.AccountNumber}).Select(x => x.First()).ToList();
Ultimately, I want to get my first query in order of Branch + Account Number distinctly.
Can they be combined or is what I have the only way to do this?
The quick and dirty solution is just to add the GroupBy chain to the end of the first query.
var qry = (from x in CustomersChecks.CustomersChecksList
where x.RoutingNumber == routingnumber &&
x.BankAccountNumber == bankAccountNumber &&
x.Branch > 0 &&
x.AccountNumber > 0
orderby x.Name
select x).GroupBy(x => new { x.Branch, x.AccountNumber})
.Select(x => x.First())
.ToList();
Or do the following by incorrupating the group by into the exist query syntax
var qry = (from x in CustomersChecks.CustomersChecksList
where x.RoutingNumber == routingnumber &&
x.BankAccountNumber == bankAccountNumber &&
x.Branch > 0 &&
x.AccountNumber > 0
orderby x.Name
group x by new { x.Branch, x.AccountNumber} into grp
select grp.First()).ToList();
var qry = CustomersChecks.CustomersChecksList.Where(x =>
x.RoutingNumber == routingnumber &&
x.BankAccountNumber == bankAccountNumber &&
x.Branch > 0 &&
x.AccountNumber > 0).OrderBy(x => x.Name)
.GroupBy(x => new { x.Branch, x.AccountNumber})
.Select(x => x.First())
.ToList();

c# - Group by and having with two counts in Linq

How can I write the follow query with Linq in C#?
SELECT MAX(A2.LINHA_PLANILHA)
FROM MD_IMP_FORCA_VENDA_DADOS_A2 A2
WHERE A2.LINHA <> '0'
AND TRIM(A2.SETORES) IS NOT NULL
AND A2.LINHA_PLANILHA <> 1
AND USUARIO = V_USUARIO
GROUP BY A2.LINHA, A2.BRICK
HAVING COUNT(A2.BRICK) > 1 AND COUNT(DISTINCT A2.SETORES) > 1;
I thought to do this:
var result = from r in dataTable.AsEnumerable()
where r.Field<string>(1) != "0"
&& r.Field<string>(2).Trim() != null
&& r.Field<Int32>(0) != 1
group r by new {Linha = r.Field<string>(1), Brick = r.Field<string>(3) } into temp
where temp.Count() > 1
select new { MaxLinha = (from r2 in temp select r2.Field<Int32>(0)).Max()};
But I don't know how to put the two COUNTS of HAVING clause in Linq query.
Any help would be appreciated.
Thanks
Zago
Perhaps:
var query = db.MD_IMP_FORCA_VENDA_DADOS_A2
.Where(x => x.LINHA != "0"
&& x.SETORES != null
&& x.SETORES.Trim() != ""
&& x.LINHA_PLANILHA <> 1
&& x.USUARIO = x.V_USUARIO
)
.GroupBy(x => new { x.LINHA, x.BRICK })
.Where(g => g.Count() > 1 && g.Select(x => x.SETORES).Distinct().Count() > 1)
.Select(g => g.Max(x => x.LINHA_PLANILHA));

Linq return first date

I have the query:
var q = db.tblArcadeGamePlays
.Where(c => c.GameID == GameID && c.ReferalID != 0 && c.ReferalID != null)
.GroupBy(r => new { r.ReferalID })
.Select(g => new { Plays = g.Count(), URL = g.Key.ReferalID })
;
tblArcadeGamePlays also has a field Date, in the group I'd like to return the earliest observed date that group contains.
How would I do this?
.Select(g => new {
Plays = g.Count(), URL = g.Key.ReferalID,
MinDate = g.Min(x => x.Date
});
you might also find the LINQ syntax easier to read/maintain here, but... the extension syntax will work too. But as LINQ:
var q = from c in db.tblArcadeGamePlays
where c.GameID == GameID && c.ReferalID != 0 && c.ReferalID != null
group c by c.ReferalID into g
select new {
Plays = g.Count(), URL = g.Key.ReferalID, MinDate = g.Min(x=>x.Date)
};
this might work
var firstIndex = q.Min(c => c.Date);
var q = db.tblArcadeGamePlays .Where(c => c.GameID == GameID && c.ReferalID != 0 && c.ReferalID != null) .GroupBy(r => new { r.ReferalID }) .Select(g => new { Plays = g.Count(), URL = g.Key.ReferalID , Date = g.Min(cc=>cc.DateField) }) ;
Replace DateField with your actual property

Categories