AND OR in a Linq Query - c#

In a Linq query I need to filter appointments by Date and Local, Date or Local.
So if GivenDate and GivenLocal are not null I need to filter by GivenDate and GivenLocal:
appointments.Where(x => x.Date == x.GivenDate && x.Local == x.GivenLocal)
If GivenDate is null then the filter would be done by Local:
appointments.Where(x => x.Local == x.GivenLocal)
And if GivenLocal is null then filter by Date:
appointments.Where(x => x.Date == x.GivenDate)
Is it possible to do this with one query instead of using IF statements and 3 queries?

appointments.Where(x =>
(x.GivenDate == null || x.Date == x.GivenDate) &&
(x.GivenLocal == null || x.Local == x.GivenLocal) && )

appointments.Where(x => ((x.GivenDate != null && x.GivenLocal != null && x.Date == x.GivenDate && x.Local == x.GivenLocal) || (x.GivenDate == null && x.Local == x.GivenLocal ) || (x.GivenLocal == null && x.Date == x.GivenDate)))

Related

check if a date is null from within a lambda expression and use an alternative date only if it is null

I have some code to search for records created between two input dates (from and to) based upon the createdDate, however we have just imported some old data and not all of the records have a createdDate which means that some records are not returned. My idea is that when there is no createdDate, I use the plannedStartDate instead. This is my original code:
mainTables = mainTables.Where(d =>
d.n.CreatedDate >= AdminSearchVm.AdminSearch.SubmittedFrom &&
d.n.CreatedDate <= AdminSearchVm.AdminSearch.SubmittedTo);
but I would like to do something like this:
mainTables = mainTables.Where(d =>
d.n.CreatedDate == null ? d.n.PlannedStartDate :
d.n.CreatedDate >=
AdminSearchVm.AdminSearch.SubmittedFrom && d.n.CreatedDate == null ?
d.n.PlannedStartDate :
d.n.CreatedDate <= AdminSearchVm.AdminSearch.SubmittedTo);
try this
mainTables = mainTables.Where(d =>
((d.n.CreatedDate == null && d.n.PlannedStartDate >= AdminSearchVm.AdminSearch.SubmittedFrom)
|| (d.n.CreatedDate != null && d.n.CreatedDate >= AdminSearchVm.AdminSearch.SubmittedFrom))
&& ((d.n.CreatedDate == null && d.n.PlannedStartDate <= AdminSearchVm.AdminSearch.SubmittedIo)
|| (d.n.CreatedDate != null && d.n.CreatedDate <= AdminSearchVm.AdminSearch.SubmittedIo)));
or you can like this
mainTables = mainTables.Where(d =>
(d.n.CreatedDate == null
&& d.n.PlannedStartDate >= AdminSearchVm.AdminSearch.SubmittedFrom
&& d.n.PlannedStartDate <= AdminSearchVm.AdminSearch.SubmittedTo)
||
(d.n.CreatedDate != null
&& d.n.CreatedDate >= AdminSearchVm.AdminSearch.SubmittedFrom
&& d.n.CreatedDate <= AdminSearchVm.AdminSearch.SubmittedIo));
Maybe you can use this approach:
mainTables = mainTables
.Select(t => new { Table = t, Date = (t.n.CreatedDate ?? t.n.PlannedStartDate) })
.Where(x => x.Date >= AdminSearchVm.AdminSearch.SubmittedFrom && x.Date <= AdminSearchVm.AdminSearch.SubmittedTo)
.Select(x => x.Table);

c# linq question about multiple where clauses

I am trying to query a database with multiple where clauses.
IQueryable<string> statusQuery = from m in _context.Flight
where m.Aircraft_Type == aircraftType
&& m.Identification_Registration == registration
&& m.Destination_Airport_City == to1
&& m.DepartureDate.ToString("yyyy-MM-dd") == date1
&& m.Origin_Airport_City == from1
orderby m.Status_Text
select m.Status_Text;
This code is working, but only if I am able to supply a value to each variable.
How can I use this with a check if e.g registration == null => do not check use
&& m.Identification_Registration == registration
if(...) doesn't work here.
You can emulate this behavior using logical operators:
IQueryable<string> statusQuery =
from m in _context.Flight
where m.Aircraft_Type == aircraftType
&& (registration == null || m.Identification_Registration == registration)
&& m.Destination_Airport_City == to1
&& m.DepartureDate.ToString("yyyy-MM-dd") == date1
&& m.Origin_Airport_City == from1
orderby m.Status_Text
select m.Status_Text;

I want to write LINQ where some condition may be null or not

I want to retrieve some data from database based on some condition, for this I'm using LINQ. But problem is that I don't know how to write LINQ when some condition may be null.
from x in _db.AirWorkOrder
join c in _db.Clients on x.ClientId equals c.Id
where x.CreatedOn >= model.StartDate && x.CreatedOn <= model.EndDate && x.ClientId == model.ClientId && x.Type == model.Type && x.WorkOrderStatus == model.Status
select new DateWisedReportItemModel
I want if the clientID, type, status have null value then it will take all the values saved in the DB. and if there are some values provided in it, then it will work according to the condition.
I presume you're asking how to wildcard things that are null. You need to make the particular clause true if your model value is null. You could do this by saying things like:
(dbcolumn == modelvalue || modelvalue == null) && ...
Or like
(dbcolumn == modelvalue == null ? dbvalue : modelvalue) && ...
Or like
(dbcolumn == modelvalue ?? dbvalue)
For example:
from x in _db.AirWorkOrder
join c in _db.Clients on x.ClientId equals c.Id
where
(x.CreatedOn >= model.StartDate ?? x.CreatedOn) &&
(x.CreatedOn <= model.EndDate == null ? x.CreatedOn : model.EndDate) &&
(x.ClientId == model.ClientId || model.ClientId == null) &&
...
I prefer the first as it is the most easy to understand. Also note carefully that it is the only one that will return the row if the row value in the db is null, because to a database null is never equal to null
I want if there is no condition given in ClientId, type and status then only date(this is mandatory) filter will apply, and if there is condition in these only then these(clientId, type and status) conditions will work
It might be most simple, in terms of code readability to do like:
var baseQuery = from x in _db.AirWorkOrder
join c in _db.Clients on x.ClientId equals c.Id
IEnumerable<...> result;
if(model.ClientId == null && model.Type == null && model.Status == null){
//search on date only
result = baseQuery.Where(x.CreatedOn >= model.StartDate && x.CreatedOn <= model.EndDate);
} else {
//search on no null client/type/status only
result = baseQuery.Where(x =>
(x.ClientId == model.ClientId || model.ClientId == null) &&
(x.Type == model.Type || model.Type == null) &&
(x.WorkOrderStatus == model.Status || model.Status == null);
}

Get parent entity according to some property filter in child table

Id like to get all the parent that doesn't have in the signature table anything with
(Roleid 1 OR Roleid 2 OR Roleid 3) AND SignatureStatus IS <> NULL
RoleId - int: 0-13
SignatureStatus - bit: True, False, Null
I have this code but i still get the parent when i shouldn't and not getting it when i should..
result = Context.APP_AuthorityHasamaForm.Where(x =>
x.UpdateTypeId == (int)UpdateType.Unit && x.AuthorityNum == authorityUnit.AuthorityNum &&
x.InsertDate >= authorityUnit.FromDate && x.HasamaFormStatus == (int)Status.Valid &&
!(x.APP_SignatureAuthorityHasamaForm.Any(s =>
s.RoleId == (int)Role.EligibilityWorker1 || s.RoleId == (int)Role.DepartmentManager2 ||
s.RoleId == (int)Role.Treasurer3 && ((bool)s.SignatureStatus || !(bool)s.SignatureStatus)))).ToList();
How about changing it to be this?
!(x.APP_SignatureAuthorityHasamaForm.Any(s =>
(s.RoleId == (int)Role.EligibilityWorker1 || s.RoleId == (int)Role.DepartmentManager2 ||
s.RoleId == (int)Role.Treasurer3) && s.SignatureStatus.HasValue))).ToList();
I don't have your class structure but here goes few fixes , put brackets outside OR condition and use .HasValue for checking non null :
.Any(s =>
(s.RoleId == (int)Role.EligibilityWorker1 || s.RoleId == (int)Role.DepartmentManager2 ||
s.RoleId == (int)Role.Treasurer3) && ((bool)s.SignatureStatus.hasValue).ToList();

Get result from multiple where conditional statements in LINQ

I am trying to get the result based upon the values of variables temp_DestinationGroupName, temp_CountryName and temp_RateTypeId.
If any of these variables are null or 0, it should not be included in where clause and rest statements should work and bring the result. I am getting zero rows using this query. Kindly suggest me something with these conditions in where clause. i tried following solutions on stackoverflow but still not getting the desired result.
var Rows = _CustomerRatesList.Where(w => (w.Id != rates.Id)
&& (w.DestinationGroupName == temp_DestinationGroupName || temp_DestinationGroupName!= null)
&& (w.CountryName == temp_CountryName || temp_CountryName!=null)
&& (w.RateTypeId == temp_RateTypeId || temp_RateTypeId !=0));
(w.DestinationGroupName == temp_DestinationGroupName || temp_DestinationGroupName!= null)
Your condition here will return true as long as your input variable temp_DestinationGroupName is not null. I don't think that's what you had in mind.
You can split in many Where to make your request more readable :
var Rows = _CustomerRatesList.Where(w => w.Id != rates.Id)
.Where(w => w.DestinationGroupName != temp_DestinationGroupName || temp_DestinationGroupName != null)
.Where(w => w.CountryName != temp_CountryName || temp_CountryName != null)
.Where(w => w.RateTypeId != temp_RateTypeId || temp_RateTypeId !=0);
Notice that you must use != in first conditioon of all Where, so you'll get all data except when it's null. In your logic, may be the conditions will be == :
var Rows = _CustomerRatesList.Where(w => w.Id != rates.Id)
.Where(w => w.DestinationGroupName == temp_DestinationGroupName || temp_DestinationGroupName == null)
.Where(w => w.CountryName == temp_CountryName || temp_CountryName == null)
.Where(w => w.RateTypeId == temp_RateTypeId || temp_RateTypeId ==0);
Each Where result is an IEnumerable, Rows will be a IEnumerable. If you want a List, just add .ToList()
I got the solution to this problem, now i am getting filtered result.
Thank you all for your time :)
var otherRows = _CustomerRatesList.Where(w => w.Id != rates.Id)
.Where(w => w.DestinationGroupName == temp_DestinationGroupName || temp_DestinationGroupName == null)
.Where(w => w.CountryName == temp_CountryName || temp_CountryName == null)
.Where(w => w.RateTypeId == temp_RateTypeId || temp_RateTypeId == 0);

Categories

Resources