Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve records from the database matching multiple values of a list

I have a problem with writing a C# linq query for retrieving data from the database, based on multiple columns of a filter list.

The list of items contains multiple columns (For example A and B) and is dynamic. My first idea was to write an any statement in an where statement, but this is not allowed in EF.

var result = _repository.Where(x => items.Any(y => x.A == y.A && x.B == y.B));

I also tried the filter first only on A, retrieve all data and filter on B, but that did not perform well.

var ListA = items.Select(x => x.A).ToList();
var result = _repository.Get(x => ListA.Contains(x.A));

An other way would be to create some c# code to generate something like this:

SELECT A,B,C,D
FROM Items 
WHERE 
    (A = 1 AND b = 1) OR 
    (A = 7 AND b = 2) OR 
    (A = 4 AND b = 3)

But there is no decent way to do this.

Has anyone an idea how to fix this issue?

like image 966
R Pelzer Avatar asked Nov 01 '18 15:11

R Pelzer


People also ask

How do I match multiple values in SQL?

Note – Use of IN for matching multiple values i.e. TOYOTA and HONDA in the same column i.e. COMPANY. Syntax: SELECT * FROM TABLE_NAME WHERE COLUMN_NAME IN (MATCHING_VALUE1,MATCHING_VALUE2);

How to check 2 values in same column sql?

Find duplicate values in one column First, use the GROUP BY clause to group all rows by the target column, which is the column that you want to check duplicate. Then, use the COUNT() function in the HAVING clause to check if any group have more than 1 element. These groups are duplicate.

How can I get multiple values in one column in MySQL?

In this case, we use GROUP_CONCAT function to concatenate multiple rows into one column. GROUP_CONCAT concatenates all non-null values in a group and returns them as a single string. If you want to avoid duplicates, you can also add DISTINCT in your query.

How do I store multiple values in one column in SQL?

You can store multiple data as delimiter separated values. Use pipe (|) or tilt (~) as the delimiter. And when we are inserting new value or updating existing value, check if the phone number already exists.


1 Answers

So, not entirely in Linq but one way to do this would be using a Predicate / PredicateBuilder (info on there here)

This would allow you to set up something like

var predicate = PredicateBuilder.False<YourType>();
foreach (var item in items)
{
    var innerpred = PredicateBuilder.True<YourType>();
    innerpred = innerpred.And(x=> x.A == item.A);
    innerpred = innerpred.And(x=> x.B == item.B);
    predicate = predicate.Or(innerpred);
}

then your conditional would be

var result = _repository.Where(predicate);

you can easily move the predicate generation into a static method or anything like that to clean up the code, but it would cause the where clause to generate SQL of

WHERE 
(A = 1 AND b = 1) OR 
(A = 7 AND b = 2) OR 
(A = 4 AND b = 3)

which is what you are after, obviously the initial loop through may be slow depending how many items you have, though if the SQL table is indexed correctly it should still be a fast query

like image 113
Gibbon Avatar answered Sep 29 '22 03:09

Gibbon