Lets say we need to select two sets from a table: "Things"
var GradeA = db.Things.Where(t=> condition1);
var GradeB = db.Things.Where(t=> !condition1 && condition2);
var DesiredList = GradeA.union(GradeB);
alternatively, we need to write a single statement to avoid union cost:
var DesiredList = db.Things.Where(t=> condtion1 || (!condition1 && condition2));
the problem is query optimizer seems to trim the expression to condition2 only.
How to preserve the priority between condition1 and condition2
a real life example workaround is :
/// <summary>
/// Gets only first BookTag for each tag word, chooses the one of this user (if exists).
/// </summary>
/// <param name="book"></param>
/// <returns></returns>
public static IQueryable<BookTag> UniqueByTags(this IQueryable<BookTag> bookTags, User user)
{
return bookTags.GroupBy(BT => BT.TagId)
.Select(g => g.Any(bt => bt.UserId == user.Id) ?
new BookTag() { User = user, Tag = g.First().Tag, Book = bookTags.First().Book } :
new BookTag() {User = g.First().User, Tag = g.First().Tag, Book = bookTags.First().Book}
);
}
Edit:
Example is getting Auto-Complete list:
- input:
str - output: things that start with
strand things that containstr(no duplicates)
Another Example:
Selecting ThingTags which have 3 properties:
ThingIDUserIDTagID
we want to select only one ThingTag for each TagID under condition that we select the one with UserID equals parameter if exists, otherwise select first ThingTag for that TagID.
Still with me ? hope so :)