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();
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've been trying to get an IQueryable with distinct and ordered values, but I've found that I can't apply a distinct after orderby or I'll lose the order.
The last query I tried was the following:
IQueryable<gbd_Pages> Listpagespages =
(from c in _db.gbd_Content
where c.IsActive == true && c.IsDeleted == false &&
c.gbd_Template_Fields.SortOrder == sortOrder
orderby c.Content ascending
select c.gbd_Pages);
With this I get repeated results.
The table I want returned is gbd_Pages which has a relation of 1 to many with gbd_Content.
With this i mean that gbd_Content will have a foreign key that will have the primary key of gbd_Pages.
I need to do a sortOrder by the table gbd_Template_Fields wich has a relation 1 to 1 with gbd_Content.
Is there a way for me to do this? I need it to be an IQueryable without converting to IEnumerable or list.
I believe what you need is something like this:
var query =
from p in _db.gbd_Pages
from pc in (from c in p.gbd_Content
where c.IsActive == true && c.IsDeleted == false &&
c.gbd_Template_Fields.SortOrder == sortOrder
orderby c.Content ascending
select c).Take(1)
orderby pc.Content ascending
select p;
So you start from one side of the relationship (to avoid the need of Distinct), then you select a single record from the many side matching the criteria and having the smaller value of the sorting field (using ordered subquery + Take(1)), and finally sort the result using the sort field value from that single child record.
I'm assuming you have inverse collection navigation property from gbd_Pages to gbd_Content. If you don't, replace the p.gbd_Content with _db.gbd_Content where c.[gbd_Content_FK] == p.[PK].
Your primary from needs to be the gbd_Pages table, rather than gbp_Content if those are the results that you want to return. I'll have to assume a foreign key here but you'd want to change to something like;
IQueryable<gbd_Pages> Listpagespages = _db.gbp_Pages
.Where(p => (from c in _db.gbd_Content
where c.IsActive == true
&& c.IsDeleted == false
select c.gbd_Pages.PrimaryKeyID)
.Any())
.Select(p => new
{
// select specific fields here...
p,
SortCol = _db.gbp_Content
.FirstOrDefault(c => c.PrimaryKeyID)
.Where(c => c.IsActive == true && c.IsDeleted == false &&
c.gbd_Template_Fields.SortOrder == sortOrder)
.Select(c => c.Content)
})
.OrderBy(v => c.SortCol);
Try this:
IQueryable<gbd_Pages> Listpagespages = _db.gbd_Content
.Select (c=>new { c.gbd_Pages })
.Where(c=>c.IsActive == true && c.IsDeleted == false &&c.gbd_Template_Fields.SortOrder == sortOrder)
.Distinct()
.OrderBy(c => c.Content)
.Select(c => c.gbd_Pages)
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 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();
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)