Click here to Skip to main content
15,880,392 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
How to get Sql datediff() function in linq, I need to get the average days between two days

my sql query is

SQL
select  year(recDate) as year1,DateName(month,(recDate)) as mnth,
relDept, count(*) as tot,
avg(datediff(day,RecDate,isnull(intl_ack,getdate())+1)) as avg1,

avg(datediff(day,RecDate,isnull(Resol_Date,getdate())+1)) as res1,
sum(case when status='Open' then 1 else 0 end) as open1

 from  Cust_Complaints  group by year(recDate),relDept,DateName(month,(recDate))


need to convert to LINQ query
Posted
Updated 26-Jun-20 7:18am
v2
Comments
Maciej Los 1-Mar-15 5:31am    
Sample data would be helpful.
Abdulnazark 1-Mar-15 6:15am    
TrID RecDate ModeOfComp RelDept Intl_Ack Resol_Date ClosureDate Status
27 19/01/14 Letter Service 00:00.0 19/02/14 19/02/14 Closed
28 05/02/14 Fax Service 00:00.0 20/02/14 20/02/14 Closed
29 25/03/14 Email Service 00:00.0 30/03/14 30/03/14 Closed
30 06/04/14 Fax Service 00:00.0 18/05/14 20/05/14 Closed
31 08/04/14 Direct Service 00:00.0 12/04/14 15/04/14 Closed
32 09/04/14 Telephone Service 00:00.0 10/04/14 12/04/14 Closed
33 28/04/14 Telephone Service 00:00.0 02/06/14 NULL Closed
34 12/05/14 Fax Construction 00:00.0 15/05/14 NULL Closed
35 12/05/14 Letter Service 00:00.0 20/05/14 NULL Closed
36 12/05/14 Email Service 00:00.0 20/05/14 NULL Open
37 30/04/14 Telephone Service 00:00.0 03/05/14 NULL Open
38 24/06/14 Telephone Service 00:00.0 02/07/14 NULL Closed
40 25/06/14 Fax NESales 00:00.0 NULL NULL Open
41 30/06/14 Fax NESales 00:00.0 NULL NULL Open
42 27/07/14 Email Service 00:00.0 03/08/14 NULL Closed
43 25/09/14 Fax Service 00:00.0 NULL NULL Open
44 30/09/14 Email Service 00:00.0 NULL NULL Open
45 30/09/14 Telephone Construction 00:00.0 31/10/14 NULL Open
Abdulnazark 1-Mar-15 6:18am    
attached sample data, It will be appreciated if you could post a complete LINQ query
Maciej Los 1-Mar-15 7:28am    
Use Reply widget if you want to notify me about comment.

The C# equivalent would be like this:
C#
DateTime endDate = ...;
DateTime startDate = ...;
int dayDiff = (endDate - startDate).Days;

The above returns the difference between two DateTimes. If you have the string representation of a date, use DateTime.Parse[^] to parse it.

You can put the above code in a method that you can call from your LINQ query.
 
Share this answer
 
Comments
Maciej Los 1-Mar-15 9:10am    
Good advice!
Please, read my comment to the question. We can't "convert" your sql query to Linq query without seeing the data.

Have a look here:
SqlMethods.DateDiffDay Method[^]
LINQ to SQL Tips and Tricks[^]

[EDIT 2]
C#
var qry = from a in md
        group a by new{Year = a.RecDate.Year, Month = a.RecDate.ToString("MMM"), Dept = a.RelDept} into grp
        select new
        {
            Year = grp.Key.Year,
            Month = grp.Key.Month,
            Dept = grp.Key.Dept,
            AvgIA = grp.Average(g=>(g.RecDate - (g.Intl_Ack !=null ? g.Intl_Ack : DateTime.Today)).Days),
            AvgRD = grp.Average(g=>(g.RecDate - (g.Resol_Date !=null ? g.Resol_Date : DateTime.Today)).Days),
            SumOp = grp.Sum(g=>g.Status=="Open" ? 1 : 0)
        };
 
Share this answer
 
v3
Comments
Abdulnazark 1-Mar-15 7:37am    
How to check the null
Maciej Los 1-Mar-15 8:29am    
See updated answer ;)
Abdulnazark 1-Mar-15 8:59am    
this fine except a.RecDate.ToString("MMM")

thank you,

the error is

An exception of type 'System.NotSupportedException' occurred in EntityFramework.SqlServer.dll but was not handled in user code

Additional information: LINQ to Entities does not recognize the method 'System.String ToString(System.String)' method, and this method cannot be translated into a store expression.
Maciej Los 1-Mar-15 9:04am    
Consider that i do not see your entity model. You have to change it to your needs.
You can use: a.RecDate.Month
Abdulnazark 1-Mar-15 9:19am    
worked below
var qry = (from a in cm.Cust_Complaints.ToList()
group a by new { Year = a.RecDate.Value.Year, Month = a.RecDate.Value.ToString("MMMM"), Dept = a.RelDept } into grp
select new
{
Year = grp.Key.Year,
Month = grp.Key.Month,
Dept = grp.Key.Dept,
AvgIA = grp.Average(g => ((g.Intl_Ack != null ? g.Intl_Ack.Value : DateTime.Today.Date) - g.RecDate.Value).Days) + 1,
AvgRD = grp.Average(g => (((g.Resol_Date != null ? g.Resol_Date.Value : DateTime.Today.Date) - g.RecDate.Value).Days) + 1),


SumOp = grp.Sum(g => g.Status == "Open" ? 1 : 0)
});
GridView1.DataSource = qry;
GridView1.DataBind();
thank you,
Solution #2 Not entirely LinqToSql
It only works because of ToList(). ToList() like AsEnumerable() causes the rest of the expression to be evaluated client-side; This is Linq, but not LinqToSql and may be unacceptable for large result sets.

ExecuteQuery
One trick if already have the SQL, is to use something like:
dataContext.ExecuteQuery<tresult>(query, optionalParameterValues);

You will have to work out what to use for TResult.

LinqToSql Executes SQL on the Server
LinqToSql takes some C# expressions & functions and maps those to the SQL so that the expression is evaluated on the server. Not all expressions can be translated, resulting in run-time errors. The solution is to find what C# can be translated into SQL code and the best place server/client to execute it.

In the OP’s case since a "group by" is done, it may actually be more efficient to force the query client-side. LinqToSql sometimes processes "group by" as n queries where n is the number of groups.

Some methods cannot be mapped to SQL. Other expressions may appear to be mapped to SQL and run on the host, but, they aren’t; for example, values that can be determined before the query on the client. So you may be able to use DateTime.Add, when the operands are available before the query, but not on a column value.

Often a little experimentation can find the C# that will work. In this case, it turns out to be easier than expected, because while Date.Add cannot be mapped, other expressions with dates can. Here some examples:

DateTime SqlDateMin = new DateTime(1999, 1, 1);
DateTime SqlDateMax = new DateTime(9999, 12, 31);

var query3 =
from ue in Company_Diff
let startDate = ue.SysRowStartDate == null ? SqlDateMin : ue.SysRowStartDate
let endDate = ue.SysRowEndDate == null ? SqlDateMax : ue.SysRowEndDate
let next = startDate + TimeSpan.FromDays(1)
let year = endDate.Value.Year
let diff = ue.SysRowEndDate - startDate

select new { ue.SysRowEndDate, ue.SysRowStartDate, diff, next, year };


You need to handle null dates, or you will get exceptions when you query data with nulls and attempt to add.
Again, to see the resulting SQL use LinqPad and view it on the SQL table.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900