mohsinali1317
mohsinali1317

Reputation: 4425

Combine linq queries together

I have to linq queries which have only a small difference between them. I am trying to merge them both.

.Where(i => 
    !i.Username.StartsWith("e-") &&
    i.SSN != null && i.SSN != "" && 
    i.DisplayName != null && i.DisplayName != "" && 
    i.LastName != null && i.LastName != "" && 
    i.FirstName != null && i.FirstName != "")
.ToList();

and the other one is

.Where(i => 
    !i.Username.StartsWith("e-") && 
    i.SSN != null && i.SSN != "" && 
    i.DisplayName != null && i.DisplayName != "" && 
    i.LastName != null && i.LastName != "" && 
    i.FirstName != null && i.FirstName != "" && 
    i.WhenChanged.HasValue && i.WhenChanged.Value > DateTime.UtcNow.Add(_whenChangedTimeSpan))
.ToList();

as you can see only the last item in where clause is different. Can they both be merge together?

Upvotes: 0

Views: 123

Answers (3)

Anu Viswan
Anu Viswan

Reputation: 18155

If you choice of either of the Linq Queries is based on a "condition", you could do the following.

var result = list.Where(
                i => !i.Username.StartsWith("e-")
                     && i.SSN != null && i.SSN != ""
                     && i.DisplayName != null && i.DisplayName != ""
                     && i.LastName != null && i.LastName != ""
                     && i.FirstName != null && i.FirstName != ""
                     && (condition? 
                     i.WhenChanged.HasValue && i.WhenChanged.Value > DateTime.UtcNow.Add(_whenChangedTimeSpan) 
                     : true)).ToList();

Upvotes: 2

Tolga Evcimen
Tolga Evcimen

Reputation: 7352

Maybe you are looking for something like this.

Create a method to do the common check

bool CommonCheck(TypeOfYourVariable i)
{
    return !i.Username.StartsWith("e-") &&
        i.SSN != null && i.SSN != "" &&
        i.DisplayName != null && i.DisplayName != "" &&
        i.LastName != null && i.LastName != "" &&
        i.FirstName != null && i.FirstName != "";
}

Use it like this:

// first
.Where(i => CommonCheck(i))
.ToList();

// secpmd
.Where(i => CommonCheck(i) &&
    i.WhenChanged.HasValue && i.WhenChanged.Value > DateTime.UtcNow.Add(_whenChangedTimeSpan))
.ToList();

Update, or you can do this:

var firstQueryResult = yourInput.Where(i => 
    !i.Username.StartsWith("e-") &&
    i.SSN != null && i.SSN != "" &&
    i.DisplayName != null && i.DisplayName != "" &&
    i.LastName != null && i.LastName != "" &&
    i.FirstName != null && i.FirstName != "" &&
).ToList();

var secondQueryResult = firstQueryResult
    .Where(i=> i.WhenChanged.HasValue && i.WhenChanged.Value > DateTime.UtcNow.Add(_whenChangedTimeSpan))
    .ToList();

Upvotes: 0

Glubus
Glubus

Reputation: 2855

Since the second query is just a subset of the first query, first execute the first query and then run the filter over that result:

var result = (...).Where(
i => !i.Username.StartsWith("e-")
&& i.SSN != null && i.SSN != ""
&& i.DisplayName != null && i.DisplayName != ""
&& i.LastName != null && i.LastName != ""
&& i.FirstName != null && i.FirstName != ""
).ToList();

var filteredResult = result.Where(i.WhenChanged.HasValue && i.WhenChanged.Value > DateTime.UtcNow.Add(_whenChangedTimeSpan)).ToList();

This will run the query only once on the database, and will do the second part in memory on your app server.

Upvotes: 0

Related Questions