Add a if statement condition to a Linq statement - c#

I am wanting a nice clean approach to adding in a conditional to an existing linq statement . I have a NEW variable personContactRoleId which will be zero or not zero.
context.PersonContactRoles
.Where(pcr => pcr.PersonId == personId);
.ToList()
.ForEach(pcr =>
{
// a lot of code
}
I was able to solve it with the iqueryable deferment of execution using an if statement, but it seems rather ugly and possibly less performant? Anything better to use?
var query = context.PersonContactRoles
.Where(pcr => pcr.PersonId == personId);
if(personContactRoleId != 0)
{
query = query.Where(b => b.PersonContactRoleId == personContactRoleId);
}
var results = query.ToList();
results.ForEach(pcr =>
{
// a lot of code
}
Again, this works, but looking for a cleaner way of doing this

The solution you have is fine, but if you want to put it all into one query without an if, you can add an additional Where condition that returns records where either personContactRoleId == 0 or prc.PersonContactRoleId == personContactRoleId is true:
context.PersonContactRoles
.Where(pcr =>
pcr.PersonId == personId &&
(personContactRoleId == 0 || pcr.PersonContactRoleId == personContactRoleId))
.ToList()
.ForEach(pcr =>
{
// a lot of code
});

This works without a need for an if block that checks that personContactRoleId is not 0
var query = context.PersonContactRoles
.Where(pcr => pcr.PersonId == personId).Where(b => {
return b.PersonContactRoleId == personContactRoleId && personContactRoleId != 0
}).ToList().ForEach(pcr =>
{
// a lot of code
}

Related

Sorting with Nulls Last

I have the following:
public IEnumerable<Customer> SortByRegion(IEnumerable<Customer> customerList)
{
return customerList.OrderBy(x => x.Region).ThenBy(x => x.ContactName);
}
It needs to Orderby Region, then by ContactName. But have the Null Regions at the bottom. I have tried the following:
customerList.OrderBy(x => x.Region != null).ThenBy(x => x.ContactName);
But id did not work. Been googling for a while. Cant seem to find it.
You can do something like this:
OrderBy(x => x.Region != null ? 1 : 0)
Well, since false < true for null last you can put
OrderBy(x => x.Region == null)

Linq remove where if the value is null

That My Linq query
var result = db.APPLICATIONS
.Where(a => Statuses.Contains(a.STATUS_ID))
.Where(a => a.TrackingNo == TrackingNo)
Statuses is a int list and TrackingNo is a nullable int (int?).
Problem:
If the TrackingNo is null then i dont want to run this clause or just skip this condition.
LINQ queries can be built in multiple steps:
var result = db.APPLICATIONS
.Where(a => Statuses.Contains(a.STATUS_ID));
if (TrackingNo != null)
{
result = result.Where(a => a.TrackingNo == TrackingNo);
}
Note that if you have a Select (a projection), you probably must build the query in multiple steps in multiple variables:
var result2 = result.Select(a => new { a.STATUS_ID });
with the result2 "built" after the if.
You can check a nullable int by using its "HasValue" property.
var result = db.APPLICATIONS
.Where(a => Statuses.Contains(a.STATUS_ID))
.Where(a => a.HasValue && (a.TrackingNo == TrackingNo))
This will cause it to evaluate the "HasValue" prior to checking the value itself. If HasValue return false, then it will never evaluate the rest of the expression (and thus not cause NullReferenceException).
If it is of type "int?", then this will work.
Just add && condition and check null. And you can use 1 where condiiton here why second where.Pls try this:
var result = db.APPLICATIONS
.Where(a => Statuses.Contains(a.STATUS_ID)
&& a.TrackingNo!=null
&& a.TrackingNo == TrackingNo)
You should first check the values of the filtering parameters before trying to add more stuff to the store expression. This would only apply the Statuses and TrackingNo filtering if the nullable TrackingNo has a value. Otherwise it will return all APPLICATIONS as IQueryable.
var result = db.APPLICATIONS.AsQueryable();
if (TrackingNo.HasValue)
{
result = result.Where(a => Statuses.Contains(a.STATUS_ID) && a.TrackingNo == TrackingNo);
}
return result;
Alternatively, this would check if you have any statuses to apply and the tracking separatedly.
var result = db.APPLICATIONS.AsQueryable();
if (Statuses != null && Statuses.Count() > 0)
{
result = result.Where(a => Statuses.Contains(a.STATUS_ID));
}
if (TrackingNo.HasValue)
{
result = result.Where(a => a.TrackingNo == TrackingNo);
}
return result;
Or third option, as it is unclear what you really wanted. This would apply the statuses filtering always and tracking only if it is available
var result = db.APPLICATIONS.Where(a => Statuses.Contains(a.STATUS_ID));
if (TrackingNo.HasValue)
{
result = result.Where(a => a.TrackingNo == TrackingNo);
}
return result;

multiple where in linq based on parameters value [duplicate]

This question already has answers here:
Linq to SQL multiple conditional where clauses
(3 answers)
Closed 7 years ago.
I want to have multiple where clauses in linq but out of them only one should execute, i was trying something like this:
public JsonResult GetPost(int? id, int? tagid, DateTime? date)
{
var ret = from data in db.Posts.Include(x => x.Tags)
.Include(x => x.Neighbourhood)
.Where((x => x.NeighbourhoodId == id) || (y => y.PostedDate == date) || third condition).ToList()
but i was unable to put second and third condition there becoz after putting dot after y, i cant see any options.
Now, out of these three, only one parameter would have value and other two would have null so, it should checks for parameter only with value.
should i write query like this, is it correct way:
if (id != null)
{
//whole query here
}
else if (tagid != null)
{
//whole query here
}
else (date != null)
{
//whole query here
}
Is it the best way to do this or something else is possible. many many thnks in advance for any suggestion.
Something like this?
var ret = from data in db.Posts.Include(x => x.Tags)
.Include(x => x.Neighbourhood)
.Where(x => x.NeighbourhoodId == (id ?? x.NeighbourhoodId) &&
x.<condition> == (tagid ?? x.<condition>) &&
x.PostedDate == (date ?? x.PostedDate).ToList();
Or like this:
var ret = from data in db.Posts.Include(x => x.Tags)
.Include(x => x.Neighbourhood)
.Where(x => id.HasValue ? x.NeighbourhoodId == id :
tagid.HasValue ? x.<condition> == tagid :
x.PostedDate == date).ToList();
Another option is to build your query more dynamically. I think this also makes your code more human readable, and your conditions can be more complex if needed (for example, build your query inside a loop or something). And you can use this with any other operator, like Include etc. Once your query is built, you can call ToList().
var ret = db.Posts.Include(x => x.Tags).Include(x => x.Neighbourhood);
if (id != null)
{
ret = ret.Where((x => x.NeighbourhoodId == id);
}
else
{
...
}
var result = ret.ToList();
You could use the following:
var ret = from data in db.Posts.Include(x => x.Tags)
.Include(x => x.Neighbourhood)
.Where(x => id == null || x.NeighbourhoodId == id)
.Where(x => date == null || y.PostedDate == date)
.ToList();
If the paramter is null, the where-clauses returns every element of the sequence. If its not null it only returns the elements which matches.

filtering results with Entity Framework

another kinda newbie question I guess. I have EF setup and now I want to select some records based on a filter. I have SomeClass with 4 items (all strings to keep things simple, lets call them string1, string2, and so on). Now, in a post I send the filter in an instance of SomeClass, but maybe not all properties are filled in.
So you might end up with string1="something", string2="bla" and string4="bla2". So string 3 = null. Now, how do I setup the query? If i try something like:
var dataset = entities.mydatabase
.Where(x => x.string1 == someclass.string1 && x.string2 == someclass.string2 && x.string3 == someclass.string3 && x.string4 == someclass.string4)
.Select(x => new { x.string1, x.string2, x.string3, x.string4}).ToList();
... I get no results, because string3=null. I could do something with checking all parameters and see if they're set and create the query based on that, but there must be something more elegant than that.
Anyone?
Thanks!
Ronald
The following will return all rows where the someclass.string is null OR equals to x.string.
var dataset = entities.mydatabase
.Where(x => someclass.string1 == null || x.string1 == someclass.string1)
.Where(x => someclass.string2 == null || x.string2 == someclass.string2)
.Where(x => someclass.string3 == null || x.string3 == someclass.string3)
.Where(x => someclass.string4 == null || x.string4 == someclass.string4)
.Select(x => new { x.string1, x.string2, x.string3, x.string4}).ToList();

Need to optimize LINQ code using Nhibernate

I 'm new to NHibernate & LINQ. I have a piece of code which I think can be optimized. Please help me to do so.
foreach (var geography in geographyList.OrderBy(x => x.Name))
{
var introductionDateDetail = environment.IntroductionDateInfo
.IntroductionDateDetails
.OrderByDescending(x => x.ApplicationDate)
.FirstOrDefault(x => x.Geography.Id == geography.Id &&
x.VaccineDetail.Id == vaccineDetail.Id &&
x.MasterForecastInfo.Id == masterforecast.Id &&
x.ViewInfo.Id == viewInfoDetail.ViewInfo.Id);
}
The for loop may iterate to about thousand records.And hence the LINQ statement is also executed that many times. Can we write a piece of code where we can execute the LINQ statement just once?
You can try something like this:
var geographiesId = geographyList.Select(g => g.Id);
var introductionDetails = environment.IntroductionDateInfo
.IntroductionDateDetails
.OrderByDescending(x => x.ApplicationDate)
.FirstOrDefault(x => geographiesId.Contains(x.Geography.Id) &&
x.VaccineDetail.Id == vaccineDetail.Id &&
x.MasterForecastInfo.Id == masterforecast.Id &&
x.ViewInfo.Id == viewInfoDetail

Categories

Resources