Sequel, pass value to pg_array query - ruby

I am looking for a way to pass an array param to a pg_array query (https://www.postgresql.org/docs/8.2/static/functions-array.html). Something like:
Model.where("array_col && ?", ids)
&& - overlap
ids = [2,3]
array_col is array containing integers for example [1,2]
When hardcoded works:
Model.where("array_col && ARRAY[2,3]")

Load the pg_array extension into the Sequel::Database object (it ships with Sequel), then:
Model.where("array_col && ?", Sequel.pg_array(ids))
Sequel also ships with a pg_array_ops extension, which allows you to do:
Model.where(Sequel.pg_array(:array_col).overlaps(ids))

Related

How do I find a collection of nodes in HtmlAgilityPack using linq to xml?

I want to extract information from various websites. I am using HtmlAgilityPack and Linq to XML. So far I have managed to extract the value from a single node in a website by writing:
var q = document.DocumentNode.DescendantNodes()
.Where(n => n.Name == "img" && n.Id == "GraphicalBoard001")
.FirstOrDefault();
But I am really interested in the whole collection of img's that start with "GraphicalBoard". I tried something like:
var q2 = document.DocumentNode.DescendantNodes()
.Where(n => n.Name == "img" && n.Id.Contains("GraphicalBoard"))
.Select...
But it seems that linq doesn't like the Contains-method, since I lose the Select option in intellisense. How can I extract all the img-tags where the Id starts with "GraphicalBoard"?
How can I extract all the img-tags where the Id starts with "GraphicalBoard"?
You had it already, just stop at the call to Where(). The Where() call filters the collection by the items that satisfies the predicate.
Though you should write it so you filter through the img descendants, not all descendants.
var query = doc.DocumentNode.Descendants("img")
.Where(img => img.Id.StartsWith("GraphicalBoard"));

Access a collection via LINQ and set a single member to a new object

I am trying to access a user object in a collection with the id = to users101 and set this to another users.
Controller.MyObject.SingleOrDefault(x => x.Id == "user101") = OtherUser();
Thanks in advance.
You can't do it with one LINQ expression.
Usually LINQ extensions works on enumerables, if MyObject is a collection you first have to find the required item and then overwrite it with the new object (moreover SingleOrDefault() will simply return null if condition is not satisfied).
You should write something like this (exact code depends on what MyObject is):
var item = Controller.MyObject.SingleOrDefault(x => x.Id == "user101");
if (item != null)
Controller.MyObject[Controller.MyObject.IndexOf(item)] = new OtherUser();
Please note that if you do not really need the check performed by SingleOrDefault() you can simplify the code (and avoid the double search performed in SingleOrDefault() and IndexOf()).
If this is "performance critical" maybe it is better to write an ad-hoc implementation that does this task in one single pass.
Try it in two lines:
var objectWithId = Controller.MyObject.SingleOrDefault(x => x.Id == "user101");
(objectWithId as WhateverTypeOfObjectOtherUserIs) = OtherUser();

Match on 2 values

I'm trying to figure out how to modify this to match on 2:
var result = _context.FirstOrDefault(c => c.CarId == carId);
I'm not sure how to tack this on. I just want to base it on c.CarId == carId && c.UserId == userId
where carId and userId are incoming params to my method that this LINQ statement resides in. I want to keep this as a lambda expression syntax.
Just do it exactly as you've written it:
var result = _context.FirstOrDefault(c => c.CarId == carId && c.UserId == userId);
There's nothing wrong with that. The lambda expression isn't restricted to compare a single property.
If you want to learn about LINQ in more detail, I'd start with LINQ to Objects, which is simpler to understand and predict. There are various tutorials around for it, and I have a blog series called Edulinq which examines each operator in detail.

DateTime and LinqToEntities

I have DateTime field, which storing date + time. I need to use only date part, so I try:
query = query.Where(p => p.CreatedDateTime.Date == DateStart);
but I get the following error:
The specified type member 'Date' is not supported in LINQ to Entities.
Only initializers, entity members, and entity navigation properties
are supported.
why and how to fix it?
what about this:
query = query.Where(p => EntityFunctions.TruncateTime(p.CreatedDateTime) == DateStart);
You cannot use extension functions in LINQ queries that result in a database hit if Entity Framework has no way to convert this into valid SQL.
There may be a more compact solution but the following should work fine:
query = query.Where(p =>
p.CreatedDateTime.Year == DateStart.Year &&
p.CreatedDateTime.Month == DateStart.Month &&
p.CreatedDateTime.Day == DateStart.Day);

Multiple Defered WHERE clause expressions in LINQ to SQL

Maybe a simple question, I'm trying to get a result from a table where the Name column contains all of an array of search terms. I'm creating a query and looping through my search strings, each time assigning the query = query.Where(...);. It appears that only the last term is being used, I supposed because I am attempting to restrict the same field each time. If I call .ToArray().AsQueryable() with each iteration I can get the cumlative restrinction behavior I'm looking for, but it there an easy way to do this using defered operators only?
Thanks!
If you're doing something like:
foreach (int foo in myFooArray)
{
query = query.where(x => x.foo == foo);
}
...then it will only use the last one since each where criteria will contain a reference to the 'foo' loop variable.
If this is what you're doing, change it to:
foreach (int foo in myFooArray)
{
int localFoo = foo;
query = query.where(x => x.foo == localFoo);
}
...and everything should be fine again.
If this is not what is happening, please provide a code sample of what you're doing...

Resources