Datediff sql query to linq lambda query - c#

How do I translate this SQL function to linq query lambda expression?
SELECT Type, DATEDIFF(day,Expiry_Date,GETDATE()) AS Days
FROM Item
GROUP BY Type, Expiry_Date;
Do I first need to create a function in my database?

from i in db.item
group i by new{
type = i.Type,
eDate = i.Expiry_date
} into grp
select new
{
type = grp.key.Type,
date = grp.key.Expiry.Date.Subtract(DateTime.Now.Date).Days
}

This should work:-
var result = db.Item.GroupBy(x => new { x.Type, x.ExpiryDate })
.Select(x => new
{
Type = x.Key.Type,
Days = (DateTime.Now.Date - x.Key.ExpiryDate).Days
};

Related

Adding Match operators dynamically in a Group Aggregate on MongoDB

I'm using MongoDB C# driver 2.4.4 in my web application. I need to group documents in a collection filtering them dynamically.
var query = collection.Aggregate()
.Match(y => y.IdLower.Contains(id))
.Match(y => y.NameLower.Contains(name))
.Group(
key => key.Id,
g => new
{
Id = g.Key
}).ToList();
I need to add or remove Match operators based to user input but I cannot figure how.
I tried something like this:
var query = collection.Aggregate();
if(!string.IsNullOrWhiteSpace(id))
query = query.Match(y => y.IdLower.Contains(id));
if (!string.IsNullOrWhiteSpace(name))
query = query.Match(y => y.NameLower.Contains(name));
query = query.Group(
key => key.Id,
g => new
{
Id = g.Key
}).ToList();
but I get syntax error Cannot imlicitly convert type System.Collection.Generic.List<<anonymous type: string Id>> to '...
How to achieve something like this?
The problem is that the type of query is IAggregateFluent<T1> (where T1 is your document type), but the return type of the .Group() method is IAggregateFluent<T2> (where T2 is an anonymous type). The compiler does not know how to implicitly convert these types, hence the error.
It depends on what you're trying to do here, but one possible way to fix this would be to return instances of T1 (your document type) from the group expression:
query = query.Group(
key => key.Id,
g => new T1 // replace "T1" with the actual name of your class
{
Id = g.Key
}).ToList();
Another option would be to assign the results of the group function to a new variable:
var grouped = query.Group(
key => key.Id,
g => new
{
Id = g.Key
}).ToList();
Hope this helps.

Group By 'MM-dd-yyyy hh-mm'

I have records of scores that I group by the date,pid,bidc and use SUM to aggregate the scores.The original field type is datetime. By grouping by date, I am getting incorrect aggregates because I have multiple sets in a given hour-min for a given day.What is the correct way to handle this and aggregate by 'MM-dd-yyyy hh-mm'
var scores = from ts in _context.Scores
select ts;
List<ScoreAgg> aggScores = scores.GroupBy(p => new { p.create_dt.Date, p.pid, p.bidc }).Select(g => new ScoreAgg()
{
pid = g.Key.pid,
bidc = g.Key.bidc,
score = g.Sum(s => s.weight),
create_dt = g.Key.Date
}).ToList<ScoreAgg>();
You can use DbFunction.CreateDateTime to build date without seconds:
scores.GroupBy(p => new {
Date = DbFunctions.CreateDateTime(p.create_dt.Year, p.create_dt.Month, p.create_dt.Day, p.create_dt.Hour, p.create_dt.Minute, second:null)
p.pid,
p.bidc
})
You should consider making a computed column on the table like
DateOnly AS CONVERT(date, [Date])
GroupBy(p => new { p.create_dt.DateOnly, p.pid, p.bidc })
and index DateOnly column to make aggregate faster. if you just do a convert inside your groupby clause Sql will not use the index defined on Date at all.

How can I write this query in linq to sql?

I'm new in linq and want to write this query:
var query = from p in behzad.rptost
where p.date.substring(0, 4) == "1395"
-->in this calc sum=p.price_moavaq+price_year
select p;
How can I write that query?
From what I assume you are trying to sum up the price_moavaq field per year.
Furthermore, by the use of the substring I guess your date field isn't of DateTime type but just a string.
So you need to use a groupby:
var query = from p in behzad.rptost
group p by p.date.substring(0, 4) into grouping
select new { Year = p.Key, Sum = p.Sum(x => x.price_moavaq);
In the case that your date field is of DateTime type then just use .Year:
var query = from p in behzad.rptost
group p by p.date.Year into grouping
select new { Year = p.Key, Sum = p.Sum(x => x.price_moavaq);

C# Dynamic Linq Where Clause

is there a way to dynamically build a Where clause in LINQ?
Example... today I query my sql db, and only ServerGroup A has issues. I return the fault codes for that group. Works. However, tomorrow, ServerGroup A & B have issues. I do not want to manually change my LINQ query, but have it dynamically add the new ServerGroup to the WHERE clause. Is this possible with LINQ? I've done it with a Sql query.
Greatly appreciate the assistance.
var query = referenceDt.AsEnumerable()
.Where(results => results.Field<string>("ServerGroup") == "A" ||
results.Field<string>("SeverGroup") == "B")
.GroupBy(results => new
{
FaultCode = results.Field<int>("FaultCode")
})
.OrderByDescending(newFaultCodes => newFaultCodes.Key.FaultCode)
.Select(newFaultCodes => new
{
FaultCode = newFaultCodes.Key.FaultCode,
Count = newFaultCodes.Count()
});
This is a perfect use case for .Contains()
var serverGroups = new string []{ "A", "B" }.ToList();
var query = referenceDt.AsEnumerable()
.Where(results => serverGroups.Contains(results.Field<string>("ServerGroup")))
.GroupBy(results => new
{
FaultCode = results.Field<int>("FaultCode")
})
.OrderByDescending(newFaultCodes => newFaultCodes.Key.FaultCode)
.Select(newFaultCodes => new
{
FaultCode = newFaultCodes.Key.FaultCode,
Count = newFaultCodes.Count()
});
where serverGroups would be dynamically generated.
You can use Contains in Linq query for SQL equivalent of IN.

Join 2 table and group 2 field in linq

I have a very simple SQL
SELECT s.shop_code
,SUM(im.amt) sum_amt
,s.cell_no#1 shop_cell
FROM tb_sn_so_wt_mst im
,tb_cm_shop_inf s
WHERE im.shop_code = s.shop_code
GROUP BY s.shop_code, s.cell_no#1)
then i try to code linq
var listResult = from warrantyMaster in listWarrantyMasters2.Records
join shopInfo in listShopInfos
on warrantyMaster.ShopCode equals shopInfo.ShopCode
i don't know group by shop code and cell no and sum atm, any one help me out of this problem
The group by syntax with some examples is explained here group clause (C# Reference) and related links.
Here is the direct translation of your SQL query (of course the field names are just my guess since you didn't provide your classes):
var query = from im in listWarrantyMasters2.Records
join s in listShopInfos
on im.ShopCode equals s.ShopCode
group im by new { s.ShopCode, s.CellNo } into g
select new
{
g.Key.ShopCode,
g.Key.CellNo,
SumAmt = g.Sum(e => e.Amt)
};
You can try this code:
var results = from warrantyMaster in listWarrantyMasters2.Records
from shopInfo in listShopInfos
.Where(mapping => mapping.ShopCode == warrantyMaster.ShopCode )
.select new
{
ShopCode = warrantyMaster.ShopCode,
ATM = listWarrantyMasters2.ATM,
ShellNo = shopInfo.ShellNo
}
.GroupBy(x=> new { x.ShopCode, x.ShellNo })
.Select(x=>
new{
ShopCode = x.Key.ShopCode,
ShellNo = x.Key.ShellNo,
SumATM = x.Sum(item=>item.ATM)
});

Categories

Resources