Linq to SQL Group by and sum in select with entity - c#

This is mysql query:
select
convert(date,convert(char(11),[Bill Date])) as date,
SUM(Amount) as total from Bills
group by [Bill Date]
order by date asc
What will be its LINQ to SQL with entitiy?

You can use LINQ GroupBy method with Sum method
You may use the DbFunctions.TruncateTime method on the BillDate datetime field to eliminate the timestamp part when grouping on the date (assuming you want to get total for each day)
var groupedSum= db.Bills.GroupBy(x => DbFunctions.TruncateTime(x.BillDate))
.Select(x => new
{
Total= x.Sum(g => g.Amount),
Date = x.Key
}).OrderBy(f=>f.Date).ToList();
This gives you a list of anonymous objects with a Day property and a Total property.
Assuming db is your db context object and Bills is a property of type DbSet<Bill>
DbFunctions.TruncateTime method is in System.Data.Entity namespace. So make sure you have a using statement to import that.

Related

Linq Multiple Joins

I have some sql tables that I need to query information from my current query that returns a single column list is:
from f in FactSales
where f.DateKey == 20130921
where f.CompanyID <= 1
join item in DimMenuItems
on f.MenuItemKey equals item.MenuItemKey
join dmi in DimMenuItemDepts
on item.MenuItemDeptKey equals dmi.MenuItemDeptKey
group f by dmi.MenuItemDeptKey into c
select new {
Amount = c.Sum(l=>l.Amount)
}
This returns the data I want and it groups correctly by the third table I join but I cannot get the Description column from the dmi table. I have tried to add the field
Description = dmi.Description
but it doesnt work. How can I get data from the third table into the new select that I am creating with this statement? Many thanks for any help.
Firstly you are using Entity Framework COMPLETELY WRONG. Linq is NOT SQL.
You shouldn't be using join. Instead you should be using Associations.
So instead, your query should look like...
from sale in FactSales
where sale.DateKey == 20130921
where sale.CompanyID <= 1
group sale by sale.Item.Department into c
select new
{
Amount = c.Sum(l => l.Amount)
Department = c.Key
}
By following Associations, you will automatically be implicitly joining.
You should not be grouping by the id of the "table" but by the actual "row", or in Object parlance (which is what you should be using in EF, since the raison d'etre of an ORM is to convert DB to Object), is that you should be grouping by the "entity" rather than they the "entity's key".
EF already knows that the key is unique to the entity.
The grouping key word only allows you to access sale and sale.Item.Department after it. It is a transform, rather than an operator like in SQL.

Select row with max value after group in Linq Nhibernate

I have a table:
Table { Id, Date, Number, Bool }
I need to group it by Number, select the row with max Date inside each group, and retrieve Id for each group. In the end I need to filter that to only have records that are !Bool. I am trying to do this with Linq Nhibernate.
This SQL seems to be doing what I want:
select Id from
(select MAX(Date) as Dt, Number as N from Table group by Number) t, Table table
where table.Date = t.Dt and table.Number = t.N and table.Bool = 0
but turns out NHibernate does not allow for subqueries to be in from. How do I write this with Linq Nhibernate?
It's also quite important for it to be efficient, so I would rather avoid having subqueries in select or where if they iterate over the whole set and (N+1) query problem.
The straightforward approach doesn't work either:
Session.Query<Table>().GroupBy(x => x.Number)
.Select(x => x.Where(y => y.Date == x.Max(z => z.Date)))...

How to write linq query from sql query using LINQ?

I have a table with two columns like BookingArrivedEnquiredTime with varchar datatype and datetime BookingArrivedEnquiredDateTime. When I execute this query in SQL Server the result give perfect with time sorted order
the sql query will be like
select BookingArrivedEnquiredTime from BookingArriveds where BookingArrivedEnquiredDateTime='2015-02-17 00:00:00.000'
order by CAST(('01/01/2000 ' + BookingArrivedEnquiredTime) AS DATETIME)
and it gives out put like this
11:27 AM
11:47 AM
11:53 AM
12:13 PM
12:50 PM
02:02 PM
02:47 PM
03:04 PM
03:16 PM
When i try this query into using linq
public ViewResult Index1(DateTime? Startdate)
{
Startdate = DateTime.Now.Date;
var fm = DateTime.Parse("01/01/2000");
var qr = from item in db.BookingArriveds
where item.BookingArrivedEnquiredDateTime == Startdate
orderby DateTime.Parse("01/01/2000 " +
item.BookingArrivedEnquiredTime.ToString())
select item;
return View(qr);
}
but it gives error like this
LINQ to Entities does not recognize the method 'System.DateTime Parse(System.String)' method, and this method cannot be translated
into a store expression.
where is wrong and I need help for how to rewrite above sql query to linq query also casting from varchar to datetime in linq?
As others have answered, this breaks because .ToString fails to translate to relevant SQL on the way into the database.
However, Microsoft provides the SqlFunctions class that is a collection of methods that can be used in situations like this.
For this case, what you are looking for here is SqlFunctions.StringConvert:
public ViewResult Index1(DateTime? Startdate)
{
Startdate = DateTime.Now.Date;
var fm = DateTime.Parse("01/01/2000");
var qr = from item in db.BookingArriveds
where item.BookingArrivedEnquiredDateTime == Startdate
orderby SqlFunctions.StringConvert("01/01/2000 " +
item.BookingArrivedEnquiredTime.ToString())
select item;
return View(qr);
}
Good when the solution with temporary variables is not desirable for whatever reasons.
You have two options:
you can do the casting and sorting on client:
db.BookingArriveds
.Where(item => item.BookingArrivedEnquiredDateTime == Startdate)
.AsEnumerable()
.OrderBy(item => DateTime.Parse("01/01/2000 " + item.BookingArrivedEnquiredTime);
or you can use SqlFunctions.DatePart to do the cast in Sql server: https://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions(v=vs.110).aspx
EDIT: DatePart function is not suitable, because it gives you only date part. To do the casting in SQL server, you should define your own sql function: https://msdn.microsoft.com/en-us/library/vstudio/dd456847(v=vs.100).aspx
The question is, why are you storing BookingArrivedEnquiredTime in a varchar column. I believe it should be part of BookingArrivedEnquiredDateTime or it should be stored as integer or numeric column

one query with groupby / count / select new

I have to make in c# a query with linq to sql. I can handle it in sql but in linq to
sql is the result not what I wanted to get.
So there is a table with:
a day, in datetime with date and time
and a kind of id
I have to count the ids for each date, the time isn't important. So the result
should be something like:
day: 2013-11-12 amountIDs: 4
People said to me, I can make a select new query and in this query I can set the day
and could count the ids, or I make a group by day. I read similar question, but it doesn't work in my case.
Could somebody help me?
I tried it with the statement below, but the days have to be grouped, so now the output is foreach datetime, like this
day: 12.12.2013 12:00:00 amountIDs: 1
day: 12.12.2013 12:10:10 amountIDs: 1
In sql I made this statement:
SELECT CONVERT(VARCHAR(20), data.dayandtime, 106) AS day, count(data.amountIds) as ids
FROM data
WHERE ( data.dayandtime >= DATEADD(day, -28, getdate()) AND (data.type = 100) AND (data.isSomething = 0) )
GROUP BY CONVERT(VARCHAR(20), data.dayandtime, 106), data.isSomthing and it works.
I saw similar cases, where people made a : from-select-new xyz statement, than I made a view of it and tried to group just the view. Like this
var query = data.GroupBy(g => g.day.Value).ToList();
var qry = from data in dbContext
group data by data.day into dataGrpd
select new
{
day= dataGrpd.Key,
amountIDs= dataGrpd.Select(x => x.Id).Distinct().Count()
};
Check This

linq select distinct date from a DataTable

I want to fetch distinct date from a DataTable. Currently I'm using the below code:
MyDataTable.DefaultView.ToTable(true, "MyDateColumn");
This code considers the time too but I don't want the time to be considered. I wrote the below code to select only Date Part but while making the distinct it considers the time too.
MyDataTable.AsEnumerable()
.Select(row => new { MyDateColumn = row.Field<DateTime>("MyDateColumn").ToString("d") }).Distinct();
Please help me to select only distinct date(i.e by ignoring time).
You can try Selecting the column by just the Date property of the column:
MyDataTable.AsEnumerable()
.Select(row => row.Field<DateTime>("MyDateColumn").Date).Distinct();

Categories

Resources