How to improve the LINQ query? - c#

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)

Related

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;

Entity Framework Core query error when include subquery

I have this EF query
var r = (from cd in _context.CentoData
.Where(c =>
(string.IsNullOrEmpty(geneName) ? true : c.Gene == geneName) &&
(string.IsNullOrEmpty(codingEffect) ? true : c.CodingEffect == codingEffect) &&
(string.IsNullOrEmpty(zygosity) ? true : c.Zygosity == zygosity) &&
(string.IsNullOrEmpty(sex) ? true : c.Sex == sex) &&
(string.IsNullOrEmpty(clinicalStatement) ? true : c.ClinicalStatement == clinicalStatement) &&
(onsetAge == null ? true : c.AgeAtDiagnosisYearsMonths < onsetAge))
from gs in _context.GnomadSnv
.Where(g => g.Chromosome == cd.Chromosome &&
g.Position == cd.Position &&
g.Ref == cd.RefNt &&
g.Alt == cd.AltNt)
.DefaultIfEmpty()
select new resultType
{
name = cd.name,
AF = g.AF
}
And it works well. But when I when I include a Contains subquery as below (line 9), it pops error saying
"The multi-part identifier "c.Chromosome" could not be bound".
patients is a string list with tens to hundreds elements.
var r = (from cd in _context.CentoData
.Where(c =>
(string.IsNullOrEmpty(geneName) ? true : c.Gene == geneName) &&
(string.IsNullOrEmpty(codingEffect) ? true : c.CodingEffect == codingEffect) &&
(string.IsNullOrEmpty(zygosity) ? true : c.Zygosity == zygosity) &&
(string.IsNullOrEmpty(sex) ? true : c.Sex == sex) &&
(string.IsNullOrEmpty(clinicalStatement) ? true : c.ClinicalStatement == clinicalStatement) &&
(onsetAge == null ? true : c.AgeAtDiagnosisYearsMonths < onsetAge) &&
(patients != null ? patients.Contains(c.RandomPatientId): true))
from gs in _context.GnomadSnv
.Where(g => g.Chromosome == cd.Chromosome &&
g.Position == cd.Position &&
g.Ref == cd.RefNt &&
g.Alt == cd.AltNt)
.DefaultIfEmpty()
select new resultType
{
name = cd.name,
AF = g.AF
}
Did I miss something here?

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

How to match list values in linq condition?

How to match list values in linq condition?
I have one list of IDs, so these ids have to match in condition and get data from one table sol how?
public ActionResult StudentSelect(
long? CompanyId,
long? CompanyLocationId,
long? ClassId,
long? SectionId,
long? AcademicId,
long? ExamId) //) //long? SectionId)
Below RegId is list of student's registration Ids
{
var RegId = (
from a in db.Student_Marks_Percentage
where a.Delete_Flag == false &&
a.Exam_Id == ExamId &&
a.Academic_Year_Id == AcademicId &&
a.Class_Id == ClassId
select a.Registration_Id)
.ToList();
List<StudentList> Student = new List<StudentList>();
if (AcademicId != null &&
CompanyId != null &&
CompanyLocationId != null &&
ClassId == null &&
SectionId == null) //&& )//&& ClassId != null) //)
{
Student = (
from a in db.Student_Re_Admission
join b in db.Student_Registration on a.Registration_Id equals b.Registration_Id
join c in db.Student_Roll_No_Assign on a.Registration_Id equals c.Registration_Id
where c.Academic_Year_Id == AcademicId &&
c.Company_ID == CompanyId &&
c.COMPANY_LOCATION_ID == CompanyLocationId &&
a.Academic_Year_Id == AcademicId &&
c.Class_Id == ClassId &&
a.Class_Id == ClassId &&
a.Section_Id == SectionId &&
c.Section_Id == SectionId &&
Here I have to compare those all list of ids to a.Registration_Id
a.Registration_Id != RegIds &&
a.Promoted == false &&
a.Delete_Flag == false
//a.Academic_Year_Id == AcademicId &&
//a.Company_ID == CompanyId &&
//a.COMPANY_LOCATION_ID == CompanyLocationId
select new StudentList()
{
Registration_Id = a.Registration_Id,
Admission_No = a.Admission_No,
Student_First_Name = a.Student_First_Name,
Student_Middle_Name = a.Student_Middle_Name,
Student_Last_Name = a.Student_Last_Name,
Set_Roll_No = c.Set_Roll_No,
Roll_Id = c.Roll_Id
})
.OrderBy(a => a.Registration_Id)
.ToList();
ViewBag.StudentList = Student.ToList();
return PartialView();
}
}
I tried like below but getting same data of student list..
var merged = new List<StudentList>(Student);
merged.Except(Student.Where(p2 => RegId.Exists(p1 => p2.Registration_Id != p1.Registration_Id)));
I think you just need to replace a.Registration_Id != RegIds with:
!RegIDs.Contains(a.Registration_Id)
First var list by which have to compare
var RegId = (from a in db.Student_Marks_Percentage
where a.Delete_Flag == false
&& a.Exam_Id == ExamId
&& a.Academic_Year_Id == AcademicId
&& a.Class_Id == ClassId
select a).ToList();
second list of which data have to get
List<StudentList> Student = new List<StudentList>();
if (AcademicId != null && CompanyId != null && CompanyLocationId != null && ClassId == null && SectionId == null) //&& )//&& ClassId != null) //)
{
Student = (from a in db.Student_Re_Admission
join b in db.Student_Registration on a.Registration_Id equals b.Registration_Id
join c in db.Student_Roll_No_Assign on a.Registration_Id equals c.Registration_Id
where c.Academic_Year_Id == AcademicId && c.Company_ID == CompanyId && c.COMPANY_LOCATION_ID == CompanyLocationId
&& a.Academic_Year_Id == AcademicId && c.Class_Id == ClassId && a.Class_Id == ClassId
&& a.Section_Id == SectionId && c.Section_Id == SectionId
//&& a.Registration_Id != RegId.Contains(a.Registration_Id)
&& a.Promoted == false && a.Delete_Flag == false
//a.Academic_Year_Id == AcademicId && a.Company_ID == CompanyId && a.COMPANY_LOCATION_ID == CompanyLocationId
select new StudentList()
{
Registration_Id = a.Registration_Id,
Admission_No = a.Admission_No,
Student_First_Name = a.Student_First_Name,
Student_Middle_Name = a.Student_Middle_Name,
Student_Last_Name = a.Student_Last_Name,
Set_Roll_No = c.Set_Roll_No,
Roll_Id = c.Roll_Id
}).OrderBy(a => a.Registration_Id).ToList();
}
merging two lists by searching following process.
var merged = Student.Where(a1 => !RegId.Any(a2 => a1.Registration_Id == a2.Registration_Id));

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 ...

Categories

Resources