I am creating a utility using a line to sql query which will load data in a datagrid.
As the data set is in excess of 80,000 records, filtering is handled by the linq query to keep the filtering off the UI thread. I cannot filter the data grid using a filter in WPF directly as applying the filter is handled soon the UI thread, which locks the window for the 3 minutes that the filter takes to apply.
The filtering options are controlled by a number of switches (the function as checkboxes), returning bool if checked.
I want to use these switches to affect the line query, for example, if the option of completed items is checked, the equivalent change to the line query would be to add completed equals true
as a where clause, however if they are not checked, I simply wish to ignore the option.
To clarify, if the check box to show completed items is not checked, I want to show all items whether completed, or not completed. If the check box to show completed items is checked, I want to show all items where completed is equal to true.
Currently, I am adding clauses to a query object called query
in the form query = query.Where(r => r.completed == true)
, however these need to be wrapped in an if statement - I cannot simply take the value of the switch as I want to ignore the filtering if the switch is false rather than specifically add a condition which checks a certain property is set to false.
Is there anything provided as a part of linq for implementing a variable line query in this way, or is the if
block the way to go about it?
Although this has been marked as a possible duplicate, I'm not certain that it is in that the solution to the other question is to use an if statement which is what I'm looking to avoid. That question was also asked over 8 years ago, and the .NET platform has changed a lot since then.
I'm aware that I can use multiple if
statements to handle this, but if there is an alternative which is more efficient and/or easier to read, I'd like to use it.
As code has been asked for,
IsBusy = true;
String sqlConnect = connectionString;
DbConnection connection = EFConnectionFactory.MakeConnection(sqlConnect);
using (var db = new DbContext(connection)) {
var query = from l in db.Batch
join d in db.Document on l.id equals d.batch_id
group d by new { batchId = l.id, l.batchName, Added = l.added, Status = l.status, PaginationLocked = l.OKDate } into g
select new {
BatchId = g.Key.batchId, BatchName = g.Key.batchName, CreatedDate = g.Min(t => t.added), g.Key.PaginationLocked, FinalisedDate = g.Max(t => t.OKDate), g
} into res
select new BatchChronologyDataModel {
BatchId = res.BatchId,
BatchName = res.BatchName,
TotalDocuments = res.g.Count(),
TotalOKayed = res.g.Where(s => s.documentOKayed != null).Count(),
TotalExported = res.g.Where(s => s.editLocked != null).Count(),
CreatedDate = res.g.Min(t => t.added),
Status = res.g.Key.Status,
PaginationLocked = res.PaginationLocked != null,
FinalisedDate = res.g.Max(t => t.OKDate),
DurationDays = DbFunctions.DiffDays(res.CreatedDate, res.FinalisedDate),
BatchAgeDays = DbFunctions.DiffDays(res.CreatedDate, DateTime.Now),
IsCompleted = res.g.Max(t => t.OKDate) != null,
};
if (this.ShowLongCycleBatches) {
query = query.Where(r => r.DurationDays > 3);
}
if (this.Completed) {
query = query.Where(r => IsCompleted == true);
}
The issue here is simply that I have multiple clauses which have to be applied in a certain order, i.e. all batched completed will remove all uncompleted items when it runs.
I wish to show the whole data set, and filter out anything which does not match the conditions if and only if an option is selected. I do not want to assume that not checking a box is equivalent to a false value.
As there are a lot of selectable options, I'd like to know if there is a way to avoid multiple if
statements - I'm not saying that I have an issue with them, but I'd worked on solutions before where I've not spotted something useful and implemented a huge solution when there was a better answer.