I have the query I need in SQL server but I'm using Entity Framework and would like the same results using LINQ. Here is the SQL:
select convert(varchar, date_recorded, 12), MAX(outdoor_temp), MAX(wind_speed)
from weatherdata
group by convert(varchar, date_recorded, 12)
order by convert(varchar, date_recorded, 12) DESC ;
This converts my datetime column to a correct format that allows me to group properly. Basically I need to be able to convert my SQL datetime to yymmdd format.
Many thanks
class Program
{
static void Main(string[] args)
{
var entries = new List<Entry>()
{
{new Entry { Date = DateTime.UtcNow, Outdoor_Temp = 10, Wind_Speed = 5 }},
{new Entry { Date = DateTime.UtcNow, Outdoor_Temp = 5, Wind_Speed = 10}},
{new Entry { Date = DateTime.UtcNow.AddDays(-1), Outdoor_Temp = 15, Wind_Speed = 7}}
};
(from e in entries
group e by e.Date.ToShortDateString() into g
select
new
{
StringDate = g.Key,
MaxWind_Speed = g.Max(entry => entry.Wind_Speed),
MaxOutdoor_Temp = g.Max(entry => entry.Outdoor_Temp)
}
).ToList().ForEach(Console.WriteLine);
}
public class Entry
{
public DateTime Date { get; set; }
public int Outdoor_Temp { get; set; }
public int Wind_Speed { get; set; }
public override string ToString()
{
return string.Format("Date : {0}, Outdoor_Temp : {1}, Wind_Speed : {2}", Date, Outdoor_Temp, Wind_Speed);
}
}
}
Related
I have an entity like:
public class TEvent
{
public int? January { get; set; }
public int? February { get; set; }
public int? March { get; set; }
public int? April { get; set; }
public int? May { get; set; }
public int? June { get; set; }
public int? July { get; set; }
public int? August { get; set; }
public int? September { get; set; }
public int? October { get; set; }
public int? November { get; set; }
public int? December { get; set; }
//and much more
}
What I want my LINQ code to achieve:
SELECT MonthCode, * FROM T_Events
CROSS APPLY (VALUES (1, January), (2, February), (3, March), (4, April), (5, May), (6, June), (7, July), (8, August), (9, September), (10, October), (11, November), (12, December)) AS CA(MonthCode, Display)
WHERE Display = -1
The problem is that I don't know how to have LINQ know it is a column name.
What I've tried
var dd = new List<object>()
{
new {January = 1 },
new {February = 2},
new {March = 3},
new {April = 4},
new { May = 5},
new {June = 6},
new {July = 7},
new {Augest = 8},
new {September = 9},
new {October = 10},
new {November = 11},
new {December = 12}
};
var q =
from events in _context.TEvents
from mds in dd
Now when I write mds. I don't get anything because of course it is of type object, but if I don't use object how would I specify custom column names and get the value of 'Display'
Expected result:
The value of Months(Jan, feb etc...) can be (0 or -1). When the Columns are converted to Rows, I get 12 rows, each with it's own MonthCode and display, now let's say for a record March and April are -1, then the 3rd and 4th record will have Display = -1 and the rest will have 0, while all will retain it's month codes
I would suggest to use linq2db.EntityFrameworkCore, note that I'm one of the creators.
This extension brings power of linq2db to EF Core projects. And library supports join to local collections.
class MonthDescription
{
public int MonthCode { get; set; }
public string Display { get; set; }
}
var months = new []
{
new MonthDescription { MonthCode = 1, Display = "January" },
new MonthDescription { MonthCode = 2, Display = "February" },
new MonthDescription { MonthCode = 3, Display = "March" },
new MonthDescription { MonthCode = 4, Display = "April" },
new MonthDescription { MonthCode = 5, Display = "May" },
new MonthDescription { MonthCode = 6, Display = "June" },
new MonthDescription { MonthCode = 7, Display = "July" },
new MonthDescription { MonthCode = 8, Display = "Augest" },
new MonthDescription { MonthCode = 9, Display = "September" },
new MonthDescription { MonthCode = 10, Display = "October" },
new MonthDescription { MonthCode = 11, Display = "November" },
new MonthDescription { MonthCode = 12, Display = "December" }
};
var query =
from event in _context.TEvents.ToLinqToDB() // switching LINQ provider
from md in months
select new
{
event,
md
};
Thanks #Svyatoslav Danyliv For your answer. I've also found another way to achieve what I want through Union.
First Write the main query:
var evAll = from child in _context.TEvents
join parent in _context.TEventDomains
on child.ID equals parent.ID
join p in _context.TPriorities
on parent.IDPriority equals p.Idpriority into PJoin
from p in PJoin.DefaultIfEmpty()
select new TEventExtended(child, p.PriorityCode)
Now I can select for each month and union the answer. like
from ev in evAll
select new TEventExtended(ev, 1, ev.January))
.Union(
from ev in evAll
select new TEventExtended(ev, 2, ev.February))
...etc etc
Here, I created a class/record which extend TEvent by 3 properties i.e. MonthCode, Display, Priority, and created constructors which copies data from the original TEvent/TEventExtended
NOTE: If you're using C# 10. You don't need to create constructors, simply use: new TEventExtended() with { MonthCode = 12, Display = ev.December}
Finally after adding 12 unions
.Union(
from ev in evAll
select new TEventExtended(ev, 12, ev.December))
.Where(x => x.Display == -1)
.OrderBy(x => x.MonthCode >= request.Month ? x.MonthCode : x.MonthCode + 12)
.ThenBy(x => x.PCode)
.Select(x =>
new MyFinalDTO
{
//projection
}).ToListAsync(cancellationToken);
In ASP.NET Core-5 Web API I have this code:
public class DashboardCountDto
{
public int? AllMandateCount { get; set; }
public int? CurrentYearMandateCount { get; set; }
}
public List<DashboardCountDto> GetDashboardFieldCount()
{
DashboardCountDto data = new DashboardCountDto();
DateTime current = DateTime.Now;
data.CurrentYearMandateCount = _context.zib_mandates.Where(m => m.CreatedDate == current.Year).Select(c => c.Id).Distinct().Count();
List<DashboardCountDto> dataCount = new List<DashboardCountDto>();
dataCount.Add(data);
return dataCount;
}
CreatedDate is DateTime datatype
This is to return the count of records for the current year.
I got this error:
Operator '==' cannot be applied to operands of type 'DateTime?' and 'int'
How do I get this corrected?
Thanks
In your line you write
data.CurrentYearMandateCount = _context.zib_mandates.Where(m => m.CreatedDate == current.Year).Select(c => c.Id).Distinct().Count();
But CreatedDate is Date Type and current.Year is int type. so If you compare with year you should write
data.CurrentYearMandateCount = _context.zib_mandates.Where(m => m.CreatedDate.Year == current.Year).Select(c => c.Id).Distinct().Count();
Hopefully it works
try it:
public List<DashboardCountDto> GetDashboardFieldCount()
{
DashboardCountDto data = new DashboardCountDto();
DateTime current = DateTime.Now;
DateTime currentYear= DateTime.Parse($"{current.Year}/01/01");
data.CurrentYearMandateCount = _context.zib_mandates.Where(m => m.CreatedDate >= currentYear).Select(c => c.Id).Distinct().Count();
List<DashboardCountDto> dataCount = new List<DashboardCountDto>();
dataCount.Add(data);
return dataCount;
}
select case statement in linq query.
Here is the query on sql:
select case when DATEDIFF(day,convert(varchar,Min([Order].CreatedOnUtc),101),convert(varchar,Max([Order].CreatedOnUtc),101)) = 0 then
Sum([Order].OrderSubtotal)
else
case when (DATEDIFF(day,convert(varchar,Min([Order].CreatedOnUtc),101),convert(varchar,Max([Order].CreatedOnUtc),101))/30) = 0 then Sum([Order].OrderSubtotal) else
Sum([Order].OrderSubtotal)/
(DATEDIFF(day,convert(varchar,Min([Order].CreatedOnUtc),101),convert(varchar,Max([Order].CreatedOnUtc),101))/30)
end
end as 'Account Value' from [order] where And Account.ID = #Act_ID
I am trying the code here:
var query = _orderRepository.Table;
query = query.Where(o => o.AccountId == accountId);
In query i am getting my value.
After query statement what should i write??
how do i write for case statement using linq???
#Manoj, may be the below code helps you. This sample C# project may solve the problem you have.
using System;
using System.Collections.Generic;
using System.Linq;
namespace DateDiffIssue
{
class Program
{
static void Main(string[] args)
{
// Preparing data
var data = new Order[] {
new Order { AccountID = 1, CreatedOnUtc = DateTime.Parse("1.01.2017 10:00"), OrderSubtotal = 100 },
new Order { AccountID = 1, CreatedOnUtc = DateTime.Parse("1.01.2017 12:00"), OrderSubtotal = 150 },
new Order { AccountID = 1, CreatedOnUtc = DateTime.Parse("1.01.2017 14:00"), OrderSubtotal = 150 }
};
// Selection
var selected = (from item in data
let accountData = data.Where(w => w.AccountID == 1)
let minDate = accountData.Min(m => m.CreatedOnUtc).Date
let maxDate = accountData.Where(w => w.AccountID == 1).Max(m => m.CreatedOnUtc).Date
let isSameDate = minDate == maxDate
let basedOn30Days = (maxDate - minDate).TotalDays / 30
let isInside30Days = (int)basedOn30Days == 0
let accountDataSum = accountData.Sum(s => s.OrderSubtotal)
select new
{
AccountValue = isSameDate ? accountDataSum :
isInside30Days ? accountDataSum :
accountDataSum / basedOn30Days
}).Distinct();
// Print each order
selected.ToList().ForEach(Console.WriteLine);
// Wait for key
Console.WriteLine("Please press key");
Console.ReadKey();
}
}
internal class Order
{
public int AccountID { get; set; }
public DateTime CreatedOnUtc { get; set; }
public int OrderSubtotal { get; set; }
}
}
select sum(DATEDIFF(day,LeaveBreakup.StartDate,LeaveBreakup.EndDate)+1)
what I want is to convert the statement to linq select statement
class LeaveBreakup
{
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
List<LeaveBreakup> Dates = new List<LeaveBreakup>();
Dates.Add(new LeaveBreakup(){StartDate = DateTime.Now.AddDays(-3), EndDate = DateTime.Now });
Dates.Add(new LeaveBreakup(){StartDate = DateTime.Now.AddDays(-2), EndDate = DateTime.Now });
LINQ BIT
var Result = (from D in Dates
select (D.EndDate - D.StartDate).TotalDays + 1)
.Sum();
If you want to know the diff without having to worry about having a negative value then wrap the calculation in Math.Abs
var Result = (from D in Dates
select Math.Abs((D.StartDate - D.EndDate).TotalDays) + 1)
.Sum();
In this example your Result is 7
I have this model:
Public Class Tbl_Exercise
<Key()> Public Property Exercise_ID() As Integer
Public Property Exercise_Employee_ID() As Integer
Public Property Exercise_Create_Date() As Date
<ForeignKey("Tbl_Exercise_Type")> _
Public Property Exercise_Type_ID() As Integer
Public Property Exercise_Duration() As Integer
Public Overridable Property Tbl_Exercise_Type As Tbl_Exercise_Type
End Class
I need to get the sum of the Exercise_Duration for each week of the year. I need to then check if the sum for the week is greater than or equal to 150. If it is, I need to +1 another variable (a count). The goal is to display this:
# of weeks you've reached 150: X out of Z
(Where X is the count of weeks greater than or equal to 150 and Z is equal to the total number of weeks in the current year.)
Final
' get number of weeks the exercise goal was reached (greater than or equal to the goal)
Dim exerciseDb = New ExerciseDbContext
Dim exercise = exerciseDb.Tbl_Exercises.Where(Function(x) x.Exercise_Employee_ID = empId)
Dim weeks = exercise.ToList.GroupBy(Function(x) CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(x.Exercise_Create_Date, CalendarWeekRule.FirstDay, DayOfWeek.Sunday))
Dim totalWeeks = 0
For Each week In weeks
Dim sum = week.Sum(Function(x) x.Exercise_Duration)
If sum > 150 Then
totalWeeks += 1
End If
Next
Debug.Print("over150: " + totalWeeks.ToString)
using System.Globalization;
DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
Calendar cal = dfi.Calendar;
var recap =
(from e in exercises
group e by cal.GetWeekOfYear(e.Exercise_Create_Date,
dfi.CalendarWeekRule,
dfi.FirstDayOfWeek)
into g
select new
{
g.Key,
Total = g.Sum(x => x.Exercise_Duration)
}
into p
where p.Total > 150
select p)
.Count();
Here is an example in C#:
public class Exercise
{
public DateTime CreateDate { get; set; }
public int Duration { get; set; }
}
class Program
{
static void Main()
{
Exercise[] ex = new Exercise[]
{
new Exercise { CreateDate = DateTime.Parse("1/1/2012"), Duration = 160 },
new Exercise { CreateDate = DateTime.Parse("1/8/2012"), Duration = 160 },
new Exercise { CreateDate = DateTime.Parse("1/15/2012"), Duration = 160 },
new Exercise { CreateDate = DateTime.Parse("2/1/2012"), Duration = 100 },
new Exercise { CreateDate = DateTime.Parse("3/1/2012"), Duration = 75 },
new Exercise { CreateDate = DateTime.Parse("3/1/2012"), Duration = 80 }
};
var weeks = ex.GroupBy(x => CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(x.CreateDate, CalendarWeekRule.FirstDay, DayOfWeek.Sunday));
int currentweek = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(DateTime.Now, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
int over150 = weeks.Where(group => group.Sum(item => item.Duration) > 150).Count();
Console.WriteLine(String.Format("# of weeks you've reached 150: {0} out of {1}", over150, currentweek));
}
}