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 ...
Related
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
}
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();
I have following method that registers a contact in database, but before register I check the contact exists or not:
bool RegisterContact(Contact contactInfo) {
bool entityExists =
_dbContext.Contacts.FirstOrDefault(
p => (p.FilesID.Equals(contactInfo.FilesID))
&& (p.EmailAddress ==
(string.IsNullOrEmpty(
contactInfo.EmailAddress)
? p.EmailAddress
: contactInfo.EmailAddress))
&&
(p.DisplayName ==
(string.IsNullOrEmpty(
contactInfo.DisplayName)
? p.DisplayName
: contactInfo.DisplayName)));
}
this query includes the fields that contain value (not null) in search condition (FilesID, EmailAddress, DisplayName)
this technique works fine in MSSQL, today i changed the database manager to PostgreSQL and use Npgsql.
All things work except above linq query, which raises an exception with message of : "could not determine data type of parameter $2"
I was forced to solve it in this way:
bool RegisterContact(Contact contactInfo)
{
Contact entityExists = null;
if (string.IsNullOrEmpty(contactInfo.EmailAddress) &&
(string.IsNullOrEmpty(contactInfo.DisplayName)))
entityExists =
_dbContext.Contacts.FirstOrDefault(
p => p.FilesID.Equals(contactInfo.FilesID));
if (!string.IsNullOrEmpty(contactInfo.EmailAddress) && string.IsNullOrEmpty(contactInfo.DisplayName))
entityExists =
_dbContext.Contacts.FirstOrDefault(
p =>
p.FilesID.Equals(contactInfo.FilesID) &&
p.EmailAddress == contactInfo.EmailAddress);
if (string.IsNullOrEmpty(contactInfo.EmailAddress) && !string.IsNullOrEmpty(contactInfo.DisplayName))
entityExists =
_dbContext.Contacts.FirstOrDefault(
p =>
p.FilesID.Equals(contactInfo.FilesID) &&
p.DisplayName == contactInfo.DisplayName);
if (!string.IsNullOrEmpty(contactInfo.EmailAddress) &&
!string.IsNullOrEmpty(contactInfo.DisplayName))
entityExists =
_dbContext.Contacts.FirstOrDefault(
p =>
p.FilesID.Equals(contactInfo.FilesID) &&
p.EmailAddress == contactInfo.EmailAddress &&
p.DisplayName == contactInfo.DisplayName);
}
Is this Npgsql bug or by design? any known solutions/workarounds for the problem?
I currently have the same cases. I think the problem is the lack of recognition, by NpgSQL, of string.IsNullOrEmpty.
I replaced the test with a check on empty string, always recognizing as not NULL the input parameter.
-- bad
var data = from art in _ctx.Set<Soleo.Model.DLAR>()
from iva in _ctx.Set<Soleo.Model.DLAI>().Where(k => k.DITTA == art.DITTA && k.COD == art.CIVA).DefaultIfEmpty()
from fam in _ctx.Set<Soleo.Model.DLFA>().Where(k => k.DITTA == art.DITTA && k.COD == art.FAM).DefaultIfEmpty()
from mar in _ctx.Set<Soleo.Model.DLMA>().Where(k => k.DITTA == art.DITTA && k.COD == art.MAR).DefaultIfEmpty()
from udm in _ctx.Set<Soleo.Model.DLUM>().Where(k => k.DITTA == art.DITTA && k.COD == art.UM).DefaultIfEmpty()
where art.DITTA == DLAUTH.Config.Current.DITTA && art.COD.Contains(sel_cod) && art.DES.Contains(sel_des)
&& (string.IsNullOrEmpty(sel_fam) || string.Compare(art.FAM, sel_fam, true) == 0)
&& (string.IsNullOrEmpty(sel_mar) || string.Compare(art.MAR, sel_mar, true) == 0)
&& (art.DIS >= sel_dis_da && art.DIS <= sel_dis_a)
select new
{
COD = art.COD,
DES = art.DES,
DES_UDM = udm.DES,
DES_MAR = mar.DES,
DES_FAM = fam.DES,
DES_CIVA = iva.DES,
MAG1 = art.MAG1,
MAG2 = art.MAG2,
DES_DIS = art.DIS == 1 ? "Si" : "No"
};
-- good:
var data = from art in _ctx.Set<Soleo.Model.DLAR>()
from iva in _ctx.Set<Soleo.Model.DLAI>().Where(k => k.DITTA == art.DITTA && k.COD == art.CIVA).DefaultIfEmpty()
from fam in _ctx.Set<Soleo.Model.DLFA>().Where(k => k.DITTA == art.DITTA && k.COD == art.FAM).DefaultIfEmpty()
from mar in _ctx.Set<Soleo.Model.DLMA>().Where(k => k.DITTA == art.DITTA && k.COD == art.MAR).DefaultIfEmpty()
from udm in _ctx.Set<Soleo.Model.DLUM>().Where(k => k.DITTA == art.DITTA && k.COD == art.UM).DefaultIfEmpty()
where art.DITTA == DLAUTH.Config.Current.DITTA && art.COD.Contains(sel_cod) && art.DES.Contains(sel_des)
&& (string.Compare(sel_fam, "", true) == 0 || string.Compare(art.FAM, sel_fam, true) == 0)
&& (string.Compare(sel_mar, "", true) == 0 || string.Compare(art.MAR, sel_mar, true) == 0)
&& (art.DIS >= sel_dis_da && art.DIS <= sel_dis_a)
select new
{
COD = art.COD,
DES = art.DES,
DES_UDM = udm.DES,
DES_MAR = mar.DES,
DES_FAM = fam.DES,
DES_CIVA = iva.DES,
MAG1 = art.MAG1,
MAG2 = art.MAG2,
DES_DIS = art.DIS == 1 ? "Si" : "No"
};
But I do not think this is the solution. I will report the case to NpgSQL.
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.
This is what i got:
int? productID = (ClientProduct != null ? (int?)ClientProduct.ProductID : null);
result = (from po in ((Chase_Media_Pro_Entity_Model)this.NavigationItem.ObjectContext).raPurchaseOrder_List
where po.ClientID == Client.CustomerID
&& ((object.Equals(po.ClientProductID, productID)) || (po.ClientProductID == (productID ?? po.ClientProductID)))
&& (po.Is_Active == (isActive ?? po.Is_Active))
&& (po.IsApproved == (isApproved ?? po.IsApproved))
orderby po.Is_Active descending, po.IsApproved ascending
select po);
Is there a way to improve this line:
&& ((object.Equals(po.ClientProductID, productID)) || (po.ClientProductID == (productID ?? po.ClientProductID)))
This was the only way i could get the right results.
&& (!productID.HasValue || (productID == po.ClientProductID))
How about
&& ((productID.HasValue && po.ClientProductID.HasValue) ? po.ClientProductID.Value = productID.Value : true)