I have the following Linq to Entity:
var details = Uow.EmployeeAttendances.GetAllReadOnly()
.Where(a => a.EmployeeId == summary.EmployeeId && a.Timestamp == summary.Date)
.ToList();
summary.Date is just the date part so the value is like this: '2014-07-20 00:00:00'
The problem is that a.TimeStamp is a DateTime field with both date and time.
So the above query always return empty
Any way I can convert a.TimeStamp just to Date so I can compare apples with apples?
The error that I get is:
The specified type member 'Date' is not supported in LINQ to Entities
Appreciate it.
DateTime fields have a Date property, so we can simply do:
var details =
Uow
.EmployeeAttendances
.GetAllReadOnly()
.Where(a => a.EmployeeId == summary.EmployeeId
&& a.TimeStamp.Date == summary.Date)
.ToList();
The right solution is:
In Entity Framework 6, you have to use DbFunctions.TruncateTime.
var dates = Uow.EmployeeAttendances.GetAllReadOnly()
.Where(a => a.EmployeeId == summary.EmployeeId && System.Data.Entity.DbFunctions.TruncateTime(a.Timestamp) == attendanceDate)
.OrderBy(a=> a.Timestamp)
.ToList();
As an alternative to using DbFunctions.TruncateTime, you can simply do the following:
var from = summary.Date;
var to = summary.Date.AddDays(1);
var details = Uow.EmployeeAttendances
.GetAllReadOnly()
.Where(a => a.EmployeeId == summary.EmployeeId && a.Timestamp >= from && a.Timestamp< to)
.ToList();
Try it
string f = summary.ToString("MM/dd/yyyy");
summary= Convert.ToDateTime(f); // time at 12:00 start date
var details = Uow.EmployeeAttendances.GetAllReadOnly()
.Where(a=>a.EmployeeId== summary.EmployeeId &&
a.Timestamp == summary).ToList();
you can use DateTime.Compare
for example
var details = Uow.EmployeeAttendances.GetAllReadOnly()
.Where(a => a.EmployeeId == summary.EmployeeId && DateTime.Compare(x.Timestamp .Date, summary.Date) == 0).ToList();
or use EntityFunctions
var details = Uow.EmployeeAttendances.GetAllReadOnly()
.Where(a => a.EmployeeId == summary.EmployeeId && EntityFunctions.TruncateTime(x.Timestamp)== EntityFunctions.TruncateTime(summary.Date)).ToList();
Related
I have to fix a query which was already written in the LINQ Lambda, I found the fix in a Simple SQL Query but now I have some trouble in converting it to LINQ Query,
Here is my SQL Query
select * from RequestItem_SubRequestItem x
where x.RequestItem_key = 1 and x.SubRequestItem_key in (
select o.SubRequestItem_key
from SubRequestItem_Entitlement o
inner join SubRequestItem sr on sr.SubRequestItem_key = o.SubRequestItem_key
where o.Entitlement_key = 2 and sr.Action = 'Add' )
And below is my LINQ C# code where I am trying to insert my fixes which include inner join.
z.Entitlements = ARMContext.Context.SubRequestItem_Entitlement
.Where(o => o.Entitlement_key == z.AccessKey && !o.Role_key.HasValue && o.Entitlement.EntitlementConfiguration.UserVisible == true
&& (ARMContext.Context.RequestItem_SubRequestItem
.Where(x => x.RequestItem_key == requestItemKey)
.Select(y => y.SubRequestItem_key)
.Contains(o.SubRequestItem_key)))
.Join(ARMContext.Context.SubRequestItems, subrq => subrq.SubRequestItem_key, temp => requestItemKey, (subrq, temp) => subrq == temp)
Where as previously the C# LINQ code looked like this
z.Entitlements = ARMContext.Context.SubRequestItem_Entitlement
.Where(o => o.Entitlement_key == z.AccessKey && !o.Role_key.HasValue && o.Entitlement.EntitlementConfiguration.UserVisible == true
&& (ARMContext.Context.RequestItem_SubRequestItem
.Where(x => x.RequestItem_key == requestItemKey)
.Select(y => y.SubRequestItem_key)
.Contains(o.SubRequestItem_key)))
When I try to insert the JOIN in the LINQ as per my conditions then I get to see this error.
What is my mistake? Can anybody tell me a correct way to do it?
I think this should Suffice your need, although you might have to make changes to the other code which are dependent on your SubRequestItem_Entitlement table with {user, add}
please have a look at that. As I am sure you will have to make those changes.
.Join(ARMContext.Context.SubRequestItems, user => user.SubRequestItem_key, subreqItems => subreqItems.SubRequestItem_key, (user, subreqItems) => new { user, subreqItems })
.Where(Action => Action.subreqItems.Action == z.ApprovalAction)
you can use this query. I exactly matched the SQL query
var query = ARMContext.Context.RequestItem_SubRequestItem
.Where(a => a.RequestItem_key == 1 && a.RequestItem_key == (ARMContext.Context.SubRequestItem_Entitlement
.Join(ARMContext.Context.SubRequestItems,
right => right.SubRequestItem_key,
left => left.SubRequestItem_key,
(right, left) => new
{
right = right,
left = left
})
.Where(x => x.right.Entitlement_key == 2 && x.left.Action == "Add" && x.right.SubRequestItem_key == a.RequestItem_key).Select(y => y.right.SubRequestItem_key)).FirstOrDefault());
I have two sql query, I have already tested both queries are working. What I need to convert to Linq query for the dropdown list(MVC C#). Are there any way to Linq query should display only date without time?
Eg only date 2015-09-30
SELECT DISTINCT DelDate from Location where
DStatus = 'true' and FState = 'true'
output
2015-09-30 14:06:37.000
2015-09-30 14:14:09.547
My second query, I need to convert linq list only
SELECT COUNT(DISTINCT CouName) AS StatusCount FROM Location where
DlStatus = 'true' and FState = 'true' and CouName = 'Alan'
As per the SQL in your question, equivalent Linq will be
SELECT DISTINCT DelDate from Location where DStatus = 'true' and FState = 'true'
var delDates = Location
.Where(l => l.DStatus == "true" && l.FState == "true")
.Select(f => f.DelDate)
.Distinct();
SELECT COUNT(DISTINCT CouName) AS StatusCount FROM Location where DlStatus = 'true' and FState = 'true' and CouName = 'Alan'
var statusCount = Location
.Where(l => l.DStatus == "true" && l.FState == "true" && l.CouName == "Alan")
.Select(f => f.CouName)
.Distinct()
.Count();
This
db.Location.Where(x=>x.DStatus == "true" && x.FState == "true")
.Select(y=>y.DelDate.Value.ToString("yyyy-MM-dd")).Distinct().ToList();
and this
db.Location.Where(x=>x.DStatus == "true" && x.FState == "true" && x.CouName == "Alan")
.Select(y=>y.CouName).Distinct().Count();
for first query to get only date you can truncate time at selection .Date will get only Date and remove Time portion.
var dates = Location.Where(l => l.DStatus && l.FState)
.Select(f => f.DelDate.Date)
.Distinct();
for second query
var count = Location.Where(l => l.DStatus && l.FState && l.CouName == "Alan")
.Select(f => f.CouName)
.Distinct()
.Count();
Using SQL Server and C#:
I have 3 tables: Employee (EmployeeId, JobDescription), CashAllowance (CashAllowanceId) and EmployeeCashAllowance (EmployeeId, CashAllowanceId, ValueTaken, DateAdded).
Employee has (EmployeeeId) as primary key, CashAllowance has (CashAllowanceId) as primary key, EmployeeCashAllowance has 2 foreign keys (EmployeeId and CashAllowanceId) related to the first 2 tables.
I need to get the list of (EmployeeCashAllowance) in a specific date + for specific CashAllowanceId + for employees having JobDescription = "Dev"
I need to achieve this in a LINQ query on lists filled from DB where list of all EmployeeCashAllowance is a property of the Employee object (each Employee object has List ListEmployeeCashAllowances as a property). What I wrote was this:
var sumValues = (from e in Employees
where (e.JobDescription == "Dev")
from c in e.ListEmployeeCashAllowances
where (c.EmployeeId == e.EmployeeId && c.CashAllowanceId == selectedCashAllowanceId && c.DateAdded == selectedDate)
select c).ToList();
But this is not working as I expected, it's returning all rows in Employee and EmployeeCashAllowance whatever the selected criteria is (even is JobDescription is not Dev and CashAllowanceId is not the selectedCashAllowanceId).
Where did I go wrong with this?
You better use join I suppose try something like this , I haven't tested so it must look like this
var sumValues = (from e in Employees
join c in EmployeeCashAllowances on e.EmployeeId equals c.EmployeeId
where ( c.CashAllowanceId == selectedCashAllowanceId && c.DateAdded == selectedDate && e.JobDescription == "Dev")
select c).ToList();
Not Tested, Just gave a try
var results = from e in Employees
from ec in e.EmployeeCashAllowances
where (e.EmployeeId == ec.EmployeeId && ec.CashAllowanceId == selectedCashAllowanceId && ec.DateAdded == selectedDate && e.JobDescription == "Dev")
select ec;
Well, I didn't expect this, but I had to change from the query to get what I want, with the restriction that I had use "Sum" and get sum of values in the list of EmployeeCashAllowance resulted:
Employees.SelectMany(e => e.ListEmployeeCashAllowances).Where(lc => lc.CashAllowanceId == selectedCashAllowanceId).Select(c => c.ValueTaken).Sum();
Note that if I don't use Sum the list returned will contain all items in all the ListEmployeeCashAllowances.
It becomes clear when you clean the formatting:
var sumValues =
from e in Employees
where
e.JobDescription == "Dev"
from c in e.ListEmployeeCashAllowances // Gotcha!!!
where
c.EmployeeId == e.EmployeeId && // Is that really necessary?
c.CashAllowanceId == selectedCashAllowanceId &&
c.DateAdded == selectedDate
select c;
Normally I use LINQ methods like:
var query = Employees
.Where(e => e.JobDescription == "Dev")
.SelectMany(e => e.ListEmployeeCashAllowances)
.Where(c =>
c.CashAllowanceId == selectedCashAllowanceId &&
c.DateAdded == selectedDate);
But 'e.ListEmployeeCashAllowances' still can be selecting all users...
A long shot, without knowing your environment, could be:
var query = Employees
.SelectMany(e => e.ListEmployeeCashAllowances)
.Where(c =>
c.JobDescription == "Dev" &&
c.CashAllowanceId == selectedCashAllowanceId &&
c.DateAdded == selectedDate);
Resolving what to do with 'query', you can simply do:
var sumValues = query.Sum(c => c.ValueTaken);
I am trying to compare dates in my linq query but my c.DateRequired is a nullable date field and I want to just compare the date without the time. How do I go about converting c.DateRequired in this case to just get the date.
IEnumerable<SalesOrder> salesOrders = _uow.Repository<SalesOrder>().Query()
.Filter(c => c.IsDeleted != true &&
(((c.DateRequired == DateTime.Today.Date)) && Period == 1) ||
(((c.DateRequired >= sDateP && c.DateRequired <= stDate)) &&
(Period == 2 || Period == 3)))
.OrderBy(q => q.OrderBy(c => c.DateCreated))
.Get()
.Select(p => new
{
SalesOrder = p,
SalesOrderDetailsList =
p.SalesOrderDetailsList.Where(pd => pd.IsDeleted != true),
salesOrderDetailsComponentsList =
p.SalesOrderDetailsList.Select(c => c.SalesOrderDetailsComponentsList),
SalesOrderDetailsComponentsInfoList =
p.SalesOrderDetailsList.Select(
i =>
i.SalesOrderDetailsComponentsList.Select(
info => info.SalesOrderDetailsComponentsInfoList))
})
.ToList()
.Select(p => p.SalesOrder);
return salesOrders;
}
Try to use something like this:
.Where(x => x.DateRequired.HasValue &&
EntityFunctions.TruncateTime(x.DateRequired.Value) == EntityFunctions.TruncateTime(DateTime.Today))
.ToList();
It works perfectly for me.
you need to use EntityFunctions.TruncateTime which accept a nullable datetime to truncate time in linq
EntityFunctions.TruncateTime(x.DateRequired) == EntityFunctions.TruncateTime(DateTime.Today)
I answer to a similar question.
The recommended way to compare dates in linq queries if you are using EntityFramework 6 is DbFunctions.TruncateTime(m.PlanDate) and for previous versions EntityFunctions.TruncateTime(m.PlanDate)
I have a lambda 'where' query, querying an Order table like this:
List<Order> returnedOrders = _session.Query<Script>()Where(s => s.orderId == orderIdParam).ToList();
I want to also check the value of a column in the related OrderDetails table. So returnedOrders has a collection of OrderDetails, i.e. returnedOrders.orderDetails
So the SQL query would look something like:
Where OrderId = 12345 and Order.OrderDetail.CreatedDate = '01-Jan-2013'
Can anyone help me with the correct syntax please?
You can use a logical AND (&&) inside the Where method:
var date = new Date(2013,1,1);
List<Order> returnedOrders =
_session.Query<Script>()
.Where(s =>
s.orderId == orderIdParam &&
s.OrderDetails.Any(d => d.CreatedDate == date))
.ToList();
You can alternatively append another Where method.
var date = new Date(2013,1,1);
List<Order> returnedOrders =
_session.Query<Script>()
.Where(s => s.orderId == orderIdParam)
.Where(s => s.OrderDetails.Any(d => d.CreatedDate == date))
.ToList();
Since you know Id of order it seems useless but something like this
from order in orders
from detail in order.Details
where
order.Id = orderId &&
order.Id == detail.OrderId &&
detail.CreateDate == createDate
select order