Using PredicateBuilder to match part of word - entity-framework-4

I'm using LinqKit predicate Builder to find a record.
I need to match the same as Like %word%
p -> is Customer Class with FirstName, LastName ect....
but when I use:
predicate = predicate.And(p => p.FirstName.Contains(searchCriteria.FirstName));
I get only Exact match.
how can I change the code to get partial match (if I look for dani I want to get both "dani" and "daniel" )
Thanks.

can you try with IndexOf?
predicate = predicate.And(p => p.FirstName.IndexOf(searchCriteria.FirstName) > -1);

Related

Rails retuning an array of ids with multiple conditions

In my controller i'm looking to return an array with 2 conditions attached.
parent_ids = StudentGuardian.where(:guardian_id => current_user.school_user.id).pluck(:student_id)
classmodule_ids = SubjectStudent.pluck (:class_id)
#homework = Homework.where("subject in ?", classmodule_ids)
So in this case I need to find a student id from a table and then I need to get a class_id from another table.
Then I am trying to display results.
Can I get both in to the one query?
I also tried #homework = Homework.where("subject in ?", parent_ids, classmodule_ids)Of course this does not work!
You just want to know if subject is in parent_ids or classmodule_ids?
So can you just merge parent_ids and classmodule_ids into one array:
# you could merge these a bunch of different ways, here's one:
search_ids = (parent_ids + classmodule_ids).uniq
# don't forget the () around ? below
#homework = Homework.where("subject in (?)", search_ids)
Or if for some reason you didn't want to combine parent_ids and classmodule_ids:
#homework = Homework.where("subject in (?) OR subject in (?)", parent_ids, classmodule_ids)
But all of that would mean subject is an id also... Is that the case?

Move specific item to last position

Let there is a model Item with attributes id, name and specific record in DB with name 'other'.
How to get in single SQL query an ActiveRecord::Relation object with items sorted in way that other item is at last position?
As temporarily solution I used Item.where.not(name: 'other') + Item.where(name: 'other') but it results in 2 queries.
NB: it's not a real code but an extremely simplified example.
Perhaps something like below will help - we read all Items, and use slice to remove the Item with name equal to other, and append it back to array at the end.
a = Item.all.tap do |arr|
arr << arr.slice!(arr.index { |t| t.name == "other"})
end
if i get you right then you're looking for a SQL query, right? Then you could try something like that:
select id, name
from (
select id, name, decode(name, 'other', 999, 1) as sort
from items
)
order by sort
I have no database right now to test the statement. But I think you get the idea.
Good luck
Resolved with adding class method to Item model:
def self.sorted
find_by_sql("SELECT * FROM items ORDER BY (CASE name WHEN 'other' THEN 0 ELSE 1 END) DESC, id ASC")
end

Test for "not equal" on array using Controller.where() possible?

Is it possible to use the '.where()' controller method to select all db-elements that are not equal to an array consisting of ID numbers?
I can easily use the '.where()' controller method to select all db elements that are equal to a list of ID numbers stored in an array:
user_event_ids = current_user.event_items.pluck(:event_id)
#user_events = Event.where(id: user_match_ids)
But I can't seem to find a way to select all db-elements that have ID numbers which ar enot in the 'user_event_ids' array.
I've tried (with no luck):
#non_user_events = Event.where('user_id not in :arr', {arr: user_event_ids})
#non_user_events = Event.where(''user_id != ?', user_event_ids)
Both do not work and cancel with errors. Any help is appreciated!
This should be the correct syntax for what you are after:
Event.where('user_id NOT IN (?)', user_event_ids)
Given excluded_ids is an Array containing the IDs you want to exclude
If you are using Rails 4:
Event.where.not(user_id: excluded_ids)
If you are using Rails 3:
Event.where('user_id NOT IN (?)', user_event_ids)
If you are using Squeel
Event.where{user_id.not_in excluded_ids}
Here is another syntax:
Event.find(:all, :conditions => ['user_id not in (?)', user_event_ids])

Ruby on Rails: Fetch database result and search through results

I have a set of IDs for a table called "brands". I want to fetch the name column for each record in the brand table without having to re-query the database using Brand.find(brand_id). Instead, is there a way to store the database results into a variable and query the variable?
Thanks.
if you already collected the records in a var #brands, you can use
name = #brands.find {|b| b.id == brand_id}.name
not a query
This will return an array of all Brands for a brand_id
Brand.find(:all, :conditions => ["brand_id = ?", brand_id])
For a collection of brand_ids
Brand.find(:all, :conditions => ["brand_id IN (?)", [brand_id1, brand_id2]])
HTH
You can write a method in your model brand.
def get_associated_brand
b = self.brand_id
brand = Brand.find(b).name
end
From your view just call this method so that in your view you ll get brand name instead of ID like
brand.get_associated_brand
instead of
brand.brand_id
About what was commented on #Harsh Gupta's answers, maybe
#filtered_brands = Brand.where(id: <some_id>)
Then you can access all info of each brand in a regular each loop.

How to implement a search query in NHibernate 3 (using NHibernate.Linq)

I'm trying to build a search query using NHibernate that will filter on parameters from several different tables and result in somewhat-reasonable SQL that can take advantage of NHibernate's lazy-loading.
Fromm reading various tips online, it seems that the latest-and-greatest way to do that is to use the QueryOver object to conditionally add in the parameters being used, as in the following snippet:
Hibernate.Criterion.QueryOver<Models.Site, Models.Site> query = NHibernate.Criterion.QueryOver.Of<Models.Site>();
if (!string.IsNullOrEmpty(state))
query = query.WhereRestrictionOn(r => r.State.StateName).IsInsensitiveLike("%" + state + "%");
if (startDate.HasValue)
query = query.Where(r => r.Events
.Where(e=>e.EventDate >= startDate.Value)
.Count() > 0
);
return query.GetExecutableQueryOver(currentSession).Cacheable().List();
(an event has a foreign-key to site)
I have two questions:
How do I filter the child objects, instead of just the parent? The sample code above gives me all the sites with a matching events, but within that site, I only want matching events. If I'm supposed to use a join or a subquery, how? I'm confused about maintaining my tree-like hierarchy with lazy-loading through a join or subquery.
Edit: this has been answered. Thanks psousa!
How do I add an or clause? I found reference to a Disjunction object, but it doesn't seem like that's available using the QueryOver method.
Edit:
I want to result in a list of sites (top level object) filtered by the site criteria, and each site should have its list of events filtered by the event criteria.
I expect it to generate SQL like the following:
SELECT *
FROM [site] s
LEFT JOIN [event] e ON s.siteID = e.siteID
WHERE e.eventDate > #eventDate
AND (s.stateCd = #state OR s.stateName LIKE #state)
I would do that query as such:
//use aliases. Optional but more practical IMHO
Site siteAlias = null;
Event eventAlias = null;
//use JoinAlias instead of JoinQueryOver to keep the condition at the "Site" level
var results = Session.QueryOver(() => siteAlias)
.JoinAlias(m => m.Event, () => eventAlias)
.Where(() => eventAlias.EventDate > eventDate)
.Where(() => siteAlias.StateCd == state || Restrictions.On(() => siteAlias.StateName).IsLike(state))
.List();
You mentioned the Disjunction class, and it may in fact be used with QueryOver, like:
var disjunction= new Disjunction();
disjunction.Add(() => siteAlias.StateCD == state);
disjunction.Add(Restrictions.On(() => siteAlias.StateName).IsLike(state));
The QueryOver query would be:
var results = Session.QueryOver(() => siteAlias)
.JoinAlias(m => m.Event, () => eventAlias)
.Where(() => eventAlias.EventDate > eventDate)
.Where(disjunction)
.List();
When using a join alias as suggested by psousa, you will get results in a strange combination of an object structure and a row structure, with the top-level objects being duplicated by the child objects that are attached to them. In order to get the results I was looking for, you can use TransformUsing and a DistinctRootEntityResultTransformer as shown in the following code:
Site siteAlias = null;
Event eventAlias = null;
var results = currentSession.QueryOver<Site>(() => siteAlias)
.JoinAlias(m => m.Event, () => eventAlias)
.Where(() => eventAlias.EventDate > eventDate)
.Where(() => siteAlias.StateCd == state || Restrictions.On(() => siteAlias.StateName).IsLike(state))
.TransformUsing(new NHibernate.Transform.DistinctRootEntityResultTransformer())
.List();

Resources