How to compare array of elements with the linq query result in c# - linq

How can i compare array of elements with the linq query. I will pass array of elements to the controller and i want to compare and display the records that only contains the passed elements.
I will pass an array of values like ["first","second","third"] and i want to compare these records with the linq query and generate the result that contains these three records

I'm not sure but you probably want something like this
String[] values = {"first", "second", "third"};
List<YourObject> query =
(from p in this.db.table
where values.Contains(p.values) select p).ToList();

Related

Groovy Sql rows

Hello I am trying to get rows using Groovy Sql connection but it returns me records as a List inside a List. The following:
Sql sql = new Sql(dataSource)
List<GroovyRowResult> row = sql.rows('select * from user where username=:userName and password=:password, [userName:'groovy',password:'123'])
returns the result as [[return record as map]]
Any one help me to figure out why the result is a List inside a List. How will I get it as a single level List using the rows method?
Your results are coming back as a list of maps, not a list of lists. Look at the ':' and ',' chars in the inner part. You can use standard groovy extraction of values from these.
In your case, it looks like you're using a primary key search, so will only return one result, so use firstRow in this case, so that you don't have to extract the single map result from the list.
See the documentation for the groovy Sql class for examples.
In the more general case where you are returning multiple rows, then your data probably looks like this:
[[username:"foo", password:"foopass"], [username:"bar", password:"barpass"]]
Assuming the line:
def results = sql.rows('select * from user')
You can then do things like spread operators:
assert results.username == ["foo", "bar"]
assert results.password == ["foopass", "barpass"]
or iterate over the results
results.each { println it.username }
==> foo
==> bar
or use any of the many Collection functions
println results.collect { "${it.username} -> ${it.password}" }
==> [ "foo -> foopass", "bar -> barpass" ]
I think your main issue was not recognising a single map entry in a list.
It doesn't return a List inside a List, it returns a List of Map with each map containing the columns selected from your select.
So if you want all of the usernames selected (as a List), you can just do:
def usernames = row.username
If you just want a single row, you can do:
GroovyRowResult row = sql.firstRow('select * from user where username=:userName and password=:password, [userName:'groovy',password:'123'])
And then this will effectively just be a map with each key being the field name selected, and each value being the value of the first row of each field

Finding items from a list in an array stored in a DB field

I have a legacy database that has data elements stored as a comma delimited list in a single database field. (I didn't design that, I'm just stuck with it.)
I have a list of strings that I would like to match to any of the individual values in the "array" in the DB field and am not sure how to do this in Linq.
My list:
List<string> items= new List<string>();
items.Add("Item1");
items.Add("Item2");
The DB field "Products" would contain data something like:
"Item1,Item3,Item4"
"Item3,Item5,Item6"
"Item2,Item7,Item6"
"Item1,Item2"
"Item1"
My first pass at the Linq query was:
var results = (from o in Order
.Where(p=> items.Contains(p.Products)
But I know that won't work. because it will only return the records that contain only "Item1" or "Item2". So with the example data above it would return 0 records. I need to have it return two records.
Any suggestions?
There is a simple clever trick for searching comma-separated lists. First, add an extra , to the beginning and end of the target value (the product list), and the search value. Then search for that exact string. So for example, you would search ,Item1,Item3,Item4, for ,Item1,. The purpose of this is to prevent false positives, i.e., Item12,Item3 finding a match for Item1, while allowing items at the beginning/end of the list to be properly found.
Then, you can use the LINQ .Any method to check that any item in your list is a match to the product list, like the following:
var results = (from o in Order
.Where(o => items.Any(i => (","+o.Products+",").Contains(","+i+",")))
One way would be to parse the list in the Products field:
var results = (from o in Order
.Where(o => items.Any(i => o.Products.Split(',').Contains(i))
But that would parse the string multiple times for each record. You could try pulling back ALL of the records, parsing each record once, then doing the comparison:
var results = from o in Order
let prods = o.Products.Split(',')
where items.Any(i => prods.Contains(i))
select o;

Querying MVC collection with Array

Im using entity framework 4 and linq/lamda expressions. Im sure its an easy one but im trying to query a collection with an array but get records which contain all the arrays values.
basically what im doing is this
var records = collection.where(x.classifications.Any(y=> Array.Contains(y.ClassificationID))).ToList()
This works in a sense that it returns records that contain any of the arrays values but how do i get only records that contain all of the values in the array.
Hope that makes sense
EDIT:
Im marking the comment below as the answer as I did have to use ALL in my query to get it to work, however I also had to re - write my query slightly. This is what i eventually had...
var records = collection.Where(x=> Array.All(c=> x.Classifications.Select(l=>l.ClassificationID).Contains(c)))
What about using All instead of Any?
var records = collection.Where(x => x.classifications.All(y => Array.Contains(y.ClassificationID)))
.ToList()

How do I filter in linq query when field needs parsing first?

I have a data table containing multiple columns and one column that stores somewhat complex text patterns - I need to parse the field to determine if a particular sub strings exist in specific positions within the larger string pattern and then if the record should be filtered out as a result.
I can't see a way to perform the parse other than by writing a C# parsing function with String.Split method calls, foreach, etc. But if I try to parse like this:
var myFilteredTable = _db.MyTable.Where(t => t.Column1 == 'Filter1'
&& ParseIsMyItemInColumn2(t) );
I get "has no supported translation to SQL" errors.
The other option I thought of was to build the initial result without the Parse:
var myFilteredTable = _db.MyTable.Where(t => t.Column1 == 'Filter1' );
and iterate through the IQueryable resultset, testing each row with the parse function, to filter out the unwanted rows, but IQueryable does not have Remove function to strip out unwanted rows nor Add function to allow me to build up a new resultset.
So how can I filter in linq when I also need to write a Parse function?
Well the "initial filter in the database then do the rest locally" is easy:
var filtered = _db.MyTable.Where(t => t.Column1 == "Filter1")
.AsEnumerable() // Do the rest locally
.Where(t => ParseIsMyItemInColumn2(t));
AsEnumerable is a simple pass through method, but because the result is typed as IEnumerable<T> rather than IQueryable<T>, the subsequent LINQ operations use the LINQ to Objects methods in Enumerable rather than the ones in Queryable.
Obviously if a lot of items match the first filter but fail the second, that won't be terribly efficient...
Unfortunately, if the "parse function" is not something that can be translated to SQL, you will need to pull the results and use LINQ to Objects:
var myFilteredTable = _db.MyTable.Where(t => t.Column1 == 'Filter1')
.AsEnumerable().Where(ParseIsMyItemInColumn2);
Note that this will stream all of the results into memory, and then perform your parse.

Imroving/Modifying LINQ query

I already have a variable containing some groups. I generated that using the following LINQ query:
var historyGroups = from payee in list
group payee by payee.Payee.Name into groups
orderby groups.Key
select new {PayeeName = groups.Key, List = groups };
Now my historyGroups variable can contain many groups. Each of those groups has a key which is a string and Results View is sorted according to that. Now inside each of those groups there is a List corresponding to the key. Inside that List there are elements and each one those element is an object of a particular type. One of it's fields is of type System.DateTime. I want to sort this internal List by date.
Can anyone help with this? May be modify the above query or a new query on variable historyGroups.
Thanks
It is not clear to me what you want to sort on (the payee type definition is missing as well)
var historyGroups = from payee in list
group payee by payee.Payee.Name into groups
orderby groups.Key
select new {
PayeeName = groups.Key,
List = groups.OrderBy(payee2 => payee2.SomeDateTimeField)
};
Is most straightforward.
If you really want to sort only by date (and not time), use SomeDateTimeField.Date.
Inside that List there are elements and each one those element is an object of a particular type. One of it's fields is of type System.DateTime
This leads me to maybe(?) suspect
List = groups.OrderBy(payee2 => payee2.ParticularTypedElement.DateTimeField)
Or perhaps even
List = groups.OrderBy(payee2 => payee2.ObjectsOfParticularType
.OfType<DateTime>()
.FirstOrDefault()
)
I hope next time you can clarfy the question a bit better, so we don't have to guess that much (and come up with a confusing answer)

Resources