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
}
Related
I have created two views that return exactly the same columns from the same tables. The only difference between the two views is they filter on different parameters. I have added these into my .dbml file
(Picture of views in dbml) This has then auto generated two classes for these two views.
In my code depending on the value of the property Filter one of the two views is queried, either current or previous. I need these views to be returned as the same type. So that IOrderedQueryable<> items has one return type.
Currently they are returning as either clientOrdersQueryCurrent or clientOrdersQueryPrevious. If I set IOrderedQueryable<> items to either one of these and attempt to cast the other type then this causes a runtime error.
IOrderedQueryable<> items;
bool filterQuery = false;
if (!string.IsNullOrEmpty(OrderNumber) || DateFrom != null || Dateto != null || !string.IsNullOrEmpty(TrackingNumber) || UserId != null)
{
filterQuery = true;
}
if (Filter == "Current")
{
if (filterQuery)
{
items = dataContext.clientOrdersQueryCurrents.Where(o => o.client_id == currentClientIdProvider.GetCurrentClientId()
&& (string.IsNullOrEmpty(OrderNumber) || o.OrderNumber.Contains(OrderNumber))
&& (DateFrom == null || o.OrderPlaced >= DateFrom)
&& (Dateto == null || o.OrderPlaced <= Dateto)
&& (string.IsNullOrEmpty(TrackingNumber) || o.TrackingReference.Contains(TrackingNumber))
&& (UserId == null || o.UserId == UserId)).OrderByDescending(o => o.OrderPlaced);
}
else
{
items = dataContext.clientOrdersQueryCurrents.Where(o => o.client_id == currentClientIdProvider.GetCurrentClientId()).OrderByDescending(o => o.OrderPlaced);
}
}
else if (Filter == "Previous")
{
if (filterQuery)
{
items = dataContext.clientOrdersQueryPrevious.Where(o => o.client_id == currentClientIdProvider.GetCurrentClientId()
&& (string.IsNullOrEmpty(OrderNumber) || o.OrderNumber.Contains(OrderNumber))
&& (DateFrom == null || o.OrderPlaced >= DateFrom)
&& (Dateto == null || o.OrderPlaced <= Dateto)
&& (string.IsNullOrEmpty(TrackingNumber) || o.TrackingReference.Contains(TrackingNumber))
&& (UserId == null || o.UserId == UserId)).OrderByDescending(o => o.OrderPlaced);
}
else
{
items = dataContext.clientOrdersQueryPrevious.Where(o => o.client_id == currentClientIdProvider.GetCurrentClientId()).OrderByDescending(o => o.OrderPlaced);
}
}
else
{
//Default call - current orders
items = dataContext.clientOrdersQueryCurrents.Where(o => o.client_id == currentClientIdProvider.GetCurrentClientId()).OrderByDescending(o => o.OrderPlaced);
}
The only thing I can currently think of to resolve this is to create a class and have the query map the result to the class after it returns.
What is the best way to do this?
The ORM I am currently using is NHibernate.
Better to map to some common class
IOrderedQueryable<CommonItem> items;
items = dataContext.clientOrdersQueryCurrents.Select(e => new CommonItem{...});
...
items = dataContext.clientOrdersQueryPrevious.Select(e => new CommonItem{...});
It can be AutoMapper's ProjectTo method
items = dataContext.clientOrdersQueryPrevious.ProjectTo<CommonItem>();
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);
}
I'm struggling with data searching algorithm, which has to retrieve some data from the database using multiple fields. Each textbox provides a given parameter, stored in the database, accessed by Entity Framework. It's working when I enter data to all fields but if I leave any field empty it doesn't retrieve any record.
My question is - How to handle empty fields. If I leave any field without data, it should just not consider this parameter during selecting from the database and select data basing on non-null parameters.
This is what I've created so far:
[HttpPost]
public ViewResult Search(string brand, string model, int? manufactDateMin,
int? manufactDateMax, int? priceMin, int? priceMax, int? engineCapMin,
int? engineCapMax, string engineType, int page = 1)
{
IEnumerable<Car> foundItems = repository.Cars
.Where(c => brand == null || c.Brand == brand)
.Where(c => model == null || c.Model == model)
.Where(c => manufactDateMin == null || manufactDateMax == null || (c.ManufactDate.Year >= manufactDateMin) && (c.ManufactDate.Year < manufactDateMax))
.Where(c => priceMin == null || priceMax == null || (c.Price >= priceMin) && (c.Price < priceMax))
.Where(c => engineCapMin == null || engineCapMax == null || (c.EngineCapacity >= engineCapMin) && (c.EngineCapacity < engineCapMax))
.Where(c => engineType == null || c.EngineType == engineType)
.OrderBy(c => c.Id)
.Skip(PageSize * (page - 1))
.Take(PageSize);
CarListViewModel VMmodel = new CarListViewModel
{
Cars = foundItems,
PagingInfo = new PagingInfo
{
CurrentPage = page,
ItemsPerPage = PageSize,
TotalItems = foundItems.Count(),
},
CarType = null
};
return View("List", VMmodel);
}
Dont use a new where statement for each comparison. combine them into one. separate them into a new line for readability. Also, your parameters are defined as strings but your comparing it to null. You will have to pass a null for this to work. If you are passing the contents of a textbox or something then the string will be "" and not a null.
.Where(c => brand == "" || c.Brand == brand) &&
(model == "" || c.Model == model) &&
((manufactDateMin == null || manufactDateMax == null || (c.ManufactDate.Year >= manufactDateMin) && (c.ManufactDate.Year < manufactDateMax)) &&
(priceMin == null || priceMax == null || (c.Price >= priceMin) && (c.Price < priceMax))) &&
(engineCapMin == null || engineCapMax == null || (c.EngineCapacity >= engineCapMin) && (c.EngineCapacity < engineCapMax))) &&
(engineType == "" || c.EngineType == engineType))
I think you should do it separately like this
IQueryable<Car> query = repository.Cars;
if (!string.IsNullOrEmpty(brand))
{
query = query.Where(x => x.Brand == brand);
}
if (!string.IsNullOrEmpty(model ))
{
query = query.Where(x => x.Model == model );
}
and after all of them you put the take and skyp, it is faster and more readable
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 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 ...