Multiple using of || and && operands - c#

I have a query using Entity Framework. It has many different operands and I am confused with its priority. I am getting the wrong result. I need all records that IsPaid == true or IsPaid == null, also all records must be TypeId == 1 or TypeId == 2, also must be CityId == 1 and CategoryId == 2. For some reason it doesn't evaluate CityId and CategoryId.
What am I doing wrong? Thanks.
var list = db.Ads.Where (x =>
x.IsPaid == true || x.IsPaid == null &&
x.TypeId == 1 || x.TypeId == 2 &&
x.CityId == 1 && x.CategoryId == 2
).ToList();

The best way to solve this problem is using brackets.
You should always use them even if you know the binding prioritys, to increase readability of your code.
(x.IsPaid == true || x.IsPaid == null) && (x.TypeId == 1 || x.TypeId == 2) && x.CityId == 1 && x.CategoryId == 2
&& has a higher proirity than ||
So false && false || true would be translated to (false && false) || true => true
Sidenote as mentioned by #Joey:
Instead of (x.IsPaid == true || x.IsPaid == null) you can write (x.IsPaid != false).

Due to operator precedence, && binds higher than ||.
If you chain Where statements, it's more clear what happens:
var list = db.Ads
.Where(x => x.IsPaid == true || x.IsPaid == null)
.Where(x=> x.TypeId == 1 || x.TypeId == 2)
.Where(x=> x.CityId == 1)
.Where(x=> x.CategoryId == 2)
.ToList();

&& has a higher precedence than ||, just like in math. So, effectively your condition is the following:
x.IsPaid == true ||
x.IsPaid == null && x.TypeId == 1 ||
x.TypeId == 2 && x.CityId == 1 && x.CategoryId == 2
If any of those expressions on separate lines are true, the whole expression is true. You have to use parentheses to clarify here:
(x.IsPaid == true || x.IsPaid == null) &&
(x.TypeId == 1 || x.TypeId == 2) &&
x.CityId == 1 &&
x.CategoryId == 2

Try this:
var list = db.Ads.Where (
(x => x.IsPaid == true || x.IsPaid == null) &&
(x.TypeId == 1 || x.TypeId == 2) &&
(x.CityId == 1 && x.CategoryId == 2)
).ToList();

Related

Getting List() From DB

public JsonResult SearchApplicantList(string SSession, string ApStatus, string StudyLevel, string SLPrograms)
{
ab db = new ab();
var SearchList = db.Students
.Where(x => x.SemesterSessioin == SSession
&& x.OverAllStatus == ApStatus
&& x.StudyLvl == StudyLevel
&& x.ProgPref1 == SLPrograms
&& x.ProgPref2 == SLPrograms
&& x.ProgPref3 == SLPrograms
&& x.progPref4 == SLPrograms).ToList();
return Json(SearchList, JsonRequestBehavior.AllowGet);
}
I want to get a list on the basis of parameters, but few cases the many parameters can be null, null means all.
How can I do this?
Programming. Step by step.
Let me explain:
There is no need to have only one line for the query.
var searchQuery = db.Students (possibly with .Where that is constant).
if (ApStatus != null) {
searchQuery = searchQuery.Where(x => x.OverAllStatus = ApStatus
}
Btw., plenty of spelling. It is App (not Ap) and Overall not OverAll - it is ONE word as per dictionary.
Anyhow, you can repeat adding where conditions as often as you want, then at the end materialize.
All where conditions are ANDed together.
This is one thing most people overlook - LINQ allows a TON of programming and manipulation of the query tree.
public JsonResult SearchApplicantList(string SSession, string ApStatus, string StudyLevel, string SLPrograms)
{
ab db = new ab();
var SearchList = db.Students;
SearchList = SearchList.Where(x => (x.SemesterSessioin == SSession || SSession ==null || SSession =="")
&& (x.OverAllStatus == ApStatus || ApStatus ==null || ApStatus =="")
&& (x.StudyLvl == StudyLevel || StudyLevel ==null || StudyLevel =="")
&& (x.ProgPref1 == SLPrograms || SLPrograms ==null || SLPrograms =="")
&& (x.ProgPref2 == SLPrograms || SLPrograms ==null || SLPrograms =="")
&& (x.ProgPref3 == SLPrograms || SLPrograms ==null || SLPrograms =="")
&& (x.progPref4 == SLPrograms|| SLPrograms == null|| SLPrograms == "").ToList();
return Json(SearchList, JsonRequestBehavior.AllowGet);
}
Apply filter by parameter/s which can not be null, for instance SSession and StudyLevel are those parameters which can not be null. So apply filter by them first
var SearchList = db.Students.Where(x => x.SemesterSessioin == SSession && x.StudyLvl == StudyLevel).ToList();
Then check rest of parameters one by one, for SLPrograms will be like:
if(!string.IsNullOrEmpty(SLPrograms))
{
SearchList = SearchList.Where(Apply Filter By SLPrograms).ToList();
}
And then for rest of Parameters. Remember, use if and if to check each parameters. Like
if(Param1)
{
//Code
}
if(Param2)
{
//Code
}

Multiple Checkbox create LINQ

I have 4 checkboxes and based on which ones the user clicks on, I need to produce the LINQ statement. As mentioned below in the comment section, if I select just one checkbox, it works fine. If I select multiple checkboxes, it returns 0 results.
The 4 checkboxes are 1) "Item1" 2) "Item2" 3) "Item3" 4) "Item4".
This is what I have far:
var entity = _w_ItemRepository.GetMany(p => p.ID == id);
/* If I select just one item it works fine. If I select multiple items get 0 result */
entity = entity.Where
(p => (p.ItemType == 1 || !item1)
&& (p.ItemType == 2 || !item2)
&& (p.ItemType == 2 || !item3)
&& (p.ItemType == 3 || !item4)
);
I suspect the &&s need to be ||s. Consider if both item1 and item2 are true then you're essentially saying:
.Where(p => p.ItemType == 1 && p.ItemType == 2)
When the intent is probably:
.Where(p => p.ItemType == 1 || p.ItemType == 2)
(It also looks like there's a typo, you specify ItemType == 2 twice.)
Try:
entity = entity.Where
(p => (p.ItemType == 1 || !item1)
|| (p.ItemType == 2 || !item2)
|| (p.ItemType == 3 || !item3)
|| (p.ItemType == 4 || !item4)
);
Or I think this may be more clear, adding each clause if itemX is true:
entity = entity.Where
(p => (item1 && p.ItemType == 1)
|| (item2 && p.ItemType == 2)
|| (item3 && p.ItemType == 3)
|| (item4 && p.ItemType == 4)
);

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();

Why is my query not returning anything

I was writing a LINQ query to filter the records based on user input and selection. Some of the inputs may not be given from the user. So i need to filter based on the given input. I tried giving value for only 1 out of 5 optional inputs. But the query is not returning anything. Please help me to find the proper query. you can better understand after seeing the query.
Code
var model = (from items in Db.Items
where ((items.ItemNo == null ||
items.ItemNo == String.Empty) ||
((items.ItemNo.CompareTo(DD.FromItemNo) >= 0) &&
(items.ItemNo.CompareTo(DD.ToItemNo) <= 0))) &&
(items.InfoTypeId == 0 ||
(items.InfoTypeId == DD.InfoType)) &&
(items.CreatedOn == null ||
(items.CreatedOn >= DD.Start &&
items.CreatedOn <= DD.End)) &&
(items.StatusId == 0 ||
(items.StatusId == DD.Status)) &&
(items.LocationId == 0 ||
(items.LocationId == DD.Location)) &&
(items.CollectionId == 0 ||
(items.CollectionId == DD.Collection))
select new ViewModel()
{
Itemid = items.Id,
INo = items.ItemNo,
BTags = (from asd in Db.BibContents
where asd.BibId == items.BibId &&
asd.TagNo == "245" &&
asd.Sfld == "a"
select asd.Value).FirstOrDefault(),
Sid = (from stat in Db.ItemStatus1
where stat.Id == items.StatusId
select stat.Description).FirstOrDefault(),
Option = DD.Option,
CurrItemNo = DD.ItemNumber
}).ToList();
You've got to check the values of DD for nulls or 0s, not those of items:
var model = (from items in Db.Items
where
(
(DD.ItemNo == null || DD.ItemNo == String.Empty)
|| (items.ItemNo.CompareTo(DD.FromItemNo) >= 0 && items.ItemNo.CompareTo(DD.ToItemNo) <= 0)
)
&& (DD.InfoTypeId == 0 || (items.InfoTypeId == DD.InfoType))
&& (DD.CreatedOn == null || (items.CreatedOn >= DD.Start && items.CreatedOn <= DD.End))
&& (DD.StatusId == 0 || (items.StatusId == DD.Status))
&& (DD.LocationId == 0 || (items.LocationId == DD.Location))
&& (DD.CollectionId == 0 || (items.CollectionId == DD.Collection))
select ...

linq to sql nullable date issue

int ddlshopID = ddlSupervisorShop.SelectedItem == null ? 0 : ddlSupervisorShop.SelectedValue.ToInt32();
DateTime today = DateTime.Now;
List<int> supervisorShopList = shops.Select(a => a.ShopID).ToList<int>();
totalSales = (from ds in db.DailySales
join p in db.Products on ds.ProductID equals p.ProductID
where ds.IsActive == true &&
p.IsActive == true &&
ds.SaleDate.Value.Month == today.Month &&
ds.SaleDate.Value.Year == today.Year &&
ddlshopID == 0 ? supervisorShopList.Contains(ds.ShopID) : ds.ShopID == ddlshopID
group ds by new
{
p.ProductCategoryID,
p.IsActive,
}
into g
select new TotalPriceDivision
{
TotalPrice = g.Sum(a => a.Quantity * a.PerPrice),
DivisionID = g.Key.ProductCategoryID
}).ToList<TotalPriceDivision>();
In this piece of code the line
ds.SaleDate.Value.Month == today.Month && ds.SaleDate.Value.Year == today.Year
doesn't affect query result. ds.SaleDate is nullable date value (not datetime) in the database. Is it because of that? If yes, how can I solve this?
where ds.IsActive && // don't compare boolean with true
p.IsActive &&
ds.SaleDate.HasValue && // add this condition
ds.SaleDate.Value.Month == today.Month &&
ds.SaleDate.Value.Year == today.Year &&
ddlshopID == 0 ? supervisorShopList.Contains(ds.ShopID) : ds.ShopID == ddlshopID
I've found what is wrong with this.
surprisingly,incredibly and stupidly
if I order my query as
where ds.IsActive == true
&& p.IsActive == true
&& ds.SaleDate.Value.Month == today.Month
&& ds.SaleDate.Value.Year == today.Year
&& ddlshopID == 0 ? supervisorShopList.Contains(ds.ShopID) : ds.ShopID == ddlshopID
date conditions doesn't effect query result and it returns wrong.
İf I order it as
where ds.IsActive == true
&& p.IsActive == true
&& ddlshopID == 0 ? supervisorShopList.Contains(ds.ShopID) : ds.ShopID == ddlshopID
&& ds.SaleDate.Value.Month == today.Month
&& ds.SaleDate.Value.Year == today.Year
it works as I expected
I still can't beleive how is it possible. And if you think there must be another reason please explain me.

Categories

Resources