Finding user that have at least one tag object in linq? - sql

I have an object User.
User 1..N Tags(string).
For instance, i have a List of Tag object. How can i query the User to find all the user that have at least 1 Tag in side the list of tags?
Thanks in advance :)

Assuming your code snippet means you have a property Tags of type Foo<string> where Foo is some sequence type, you could just use:
var taggedUsers = users.Where(user => tags.Any(tag => user.Tags.Contains(tag));
(Actually, that's assuming you have a list of strings as Tags - the question is somewhat unclear. However, hopefully it'll be enough to sort you out.)
EDIT: Okay, with the details in the comments, I think you probably just need:
var taggedUsers = users.Where(user => tags.Any(tag => user.Tags
.Select(t => t.Value)
.Contains(tag));

Related

nhibernate queries SubQueryExpression

Can someone explain me what are NHibernate SubQueryExpression based queries. Any links with concrete examples are very welcome.
Thanks
Update:
Let's say that I have one entity named Beach. That beach can have many images. I want to select Beach entity and it;s first image from Images collection. I want to carry arround only that selected image object, or if I select only second object to carry only that object.
I do not want to access like Images.First() cause that will initialize all collection, if you need more info, plase ask.
var query = session.QueryOver(() => vehicleAlias)
.Left.JoinAlias(() => vehicleAlias.VehicleRegistrations, () => vehicleRegistrationAlias)
.WithSubquery.WhereProperty(() => vehicleRegistrationAlias.RegistrationExpiryDate).Eq(
QueryOver.Of(() => vehicleRegistrationAlias2)
.Where(() => vehicleRegistrationAlias2.Vehicle.Id == vehicleAlias.Id)
.Select(Projections.Max<VehicleRegistration>(ps => ps.RegistrationExpiryDate)));
query.Left.JoinAlias(() => vehicleRegistrationAlias.VehicleRegistrants, () => vehicleRegistrantAlias)
.Where(() => vehicleRegistrantAlias.Client.Id == clientId);
This is a subquery I just wrote for my work that took me a while to write. I don't really know what you are asking in specific but here is a sample. If you have any questions on it let me know.
.Select(Projections.Max(ps => ps.RegistrationExpiryDate))) This line does all the work in the sub query. It selects the most recent vehicle registration. Vehicle registration alias 2 is the object being queried as a sub query.
So this will pull back only the current vehicle registration for a vehicle. One vehicle may have many vehicle registrations. Its the .Select statement that can be modified into something like .OrderById.Desc.SelectTop(1) or something like that.
I hope this edit helps.

RavenDB - Get IDs of root property within a non-root level property

With RavenDB, is it possible to get the IDs of a property within another property? For example, if Foo has a list of Bar objects, and each Bar object has a SnuhId property, can I use an Include that gets the IDs of each Snuh property?
I tried the query below, but I get a RavenDB exception: index out of range. In this query, ApplicationServer is a root element, and it has a list of ApplicationsWithOverrideGroup objects. Each of those objects has an ApplicationId property. It's the ApplicationId that I want to get in the include.
IEnumerable<ApplicationServer> appServers = QueryAndCacheEtags(session =>
session.Advanced.LuceneQuery<ApplicationServer>()
.Include(x => x.CustomVariableGroupIds)
// This is the line I'm trying to make work:
.Include(x => (from item in x.ApplicationsWithOverrideGroup select item.ApplicationId).ToList())
).Cast<ApplicationServer>();
Either of these approaches appears to be working. Need to thoroughly test.
.Include(x => x.ApplicationsWithOverrideGroup)
or
.Include(x => x.ApplicationsWithOverrideGroup[0].ApplicationId)
If that first option is indeed working, then a property, specified in an Include(), will include the ID properties within it. Is that right?
I'm not sure if both of those are really working, but they seem to be. If they both work, I wonder if one is better than the other...
Ok, that's NOT WORKING. The NumberOfRequests is increasing, which I'm guessing means the number of trips to the DB is increasing, instead of just what's in the session.
Ok, none of those suggestions worked in the question above. I think what has to be done is to include the IDs of the nested properties in the root object.
And that's what I did, and I was able to get the NumberOfRequests on the session object down to one. Curiously, I had to change this:
// Not using this, at least for now, because it increased the NumberOfRequests on the session...
appServer.CustomVariableGroups = new ObservableCollection<CustomVariableGroup>(
QueryAndCacheEtags(session => session.Load<CustomVariableGroup>(appServer.CustomVariableGroupIds)).Cast<CustomVariableGroup>());
To this:
// ... however, this kept the NumberOfRequests to just one. Not sure why the difference.
appServer.CustomVariableGroups = new ObservableCollection<CustomVariableGroup>();
foreach (string groupId in appServer.CustomVariableGroupIds)
{
appServer.CustomVariableGroups.Add(QuerySingleResultAndCacheEtag(session => session.Load<CustomVariableGroup>(groupId)) as CustomVariableGroup);
}

Mapped two arrays... now... can i map three?

This mapping worked:
#fbc = FbComments.where("reviewee_id = ?", current_user.id)
#users = User.order("last_name")
#fb_comments = #fbc.map! { |fb| [fb, #users.find_by_id(fb.user_id)] }
So two arrays are mapped... one with comments and one with the user data of the person that made the comments. But I also need the user's profile picture data. Do i change the original mapping method to include a third array somehow (e.g. #fbc + #users + #pictures), or do i have to map another array on the result of mapping the first two (e.g. #fb_comments + #pictures)?
Profile pictures, like comments, have a user_id that is matched to the id of the user who made the comments.
Thanks.
I'm not sure why you're doing this the way you are. Why not use a join (.includes) to get everything in one query?
#fbc = FbComments.where("reviewee_id = ?", current_user.id).includes(:user => :picture)
#fbc.first.user # => The first user in the results
#fbc.first.user.picture # => The first user's picture
(I'm assuming here that profile picture data is its own model called Picture. Change it to fit your app if necessary.)
Take a look at the documentation and scroll down to "Eager loading of associations."

rails scope filtering

Hey guys, I have the following scope:
scope :expires_within, lambda
{|time| where("created_at BETWEEN ? AND ?", 30.days.ago,
time.from_now - 30.days)}
It's not all that important, it works.
This simply gives me all of the objects in my database which were created within a certain time frame. What I want to do is filter this scope such that it removes some of the objects.
The above scope is on a model named Post. I have another model named Lock which "belongs to" a Post, and each Post "has many" Locks. So this means that there is a foreign key on each lock with the id of its corresponding Post.
What I want to accomplish is the following: I want to filter out the posts from the above scope which do not have any locks. So from an abstract/high-level view: I want to get the posts returned from the above scope and remove any which have any associated locks (even if just one).
Is this possible? Would I have to use some form of compound query, using something like except? I'd appreciate any help.
I currently have something that works, but I have a nagging feeling that it isn't very efficient, perhaps it can be done on the database by modifying the above scope and be more efficient:
Post.expires_within(1.day) - Lock.all.collect { |lock| lock.post }
So this basically gets the collection of posts, then it fetches each of the locks' posts and dumps them all into an array which is then subtracted from the original set of posts.
Someone who has already experienced this problem was kind enough to help me out on IRC (Radar), and pointed me to this answer. Now my new scope is the following:
scope :not_locked, lambda { joins("LEFT JOIN locks on
(posts.id = locks.post_id)").where("locks.post_id IS NULL") }
scope :expires_within, lambda {|time| where("posts.created_at BETWEEN ? AND ?",
30.days.ago, time.from_now - 30.days).not_locked }
And it works very well. Hope that helps anyone else out there with the same problem.
With plain ActiveRelation, string-based LEFT JOINs are unavoidable; however, you can greatly simplify the BETWEEN calculations using the Ruby Range class:
scope :expires_within, lambda { |time|
where(:created_at => 30.days.ago..(time.from_now - 30.days)) }
You should be do it with a subquery, something like...
scope :without_locks, :conditions => "not exists(select * from locks where posts.id = locks.post_id)"

kohana ORM question

i am using kohana ORM in order to get some results from the database. My problem is: even though i have consulted the documentation, i can't find a way to select only the column i am interested in. To be more explicit, i have:
$sale_stock = Model::factory('product_type')
->where('product_type_id','=', $id )
-> find_all();
var dumping it, it selects me all the "SELECT product_type.* from product_type where etc".
But i want to select only the 'stock' field from the salestock table. doing find('stock') instead find_all() returns a weired object... Where am i wrong, and how can i actually select only the column 'stock' using kohana orm?
thank you!
ORM methods find() and find_all() always select all table columns, so there is two ways to get specified fields:
Load full table rows and get columns
from it:
$sale_stock = Model::factory('product_type')
->where('product_type_id','=', $id )
-> find_all();
// get array of id=>stock values
$columns = $sale_stock->as_array('id', 'stock');
Create special method in model using
Query Builder:
// model Model_Product_Type
public function get_stocks($product_type_id)
{
return DB::select(array('stock'))
->from($this->_table_name)
->where('product_type_id', '=', $product_type_id)
->execute($this->_db);
}
I realise this isn't exactly what you're looking for, but I've pulled the following from the Kohana documentation ...
$articles = ORM::factory('article')->select_list('id', 'title');
foreach ($articles as $id => $title)
{
// Display a list of links
echo html::anchor('articles/'.$id, $title);
}
// Display a dropdown list
echo form::dropdown('articles', $articles);
You could think of it as a discount, two fields for the price of one.
It's common practice for ORMs to return a 'non-standard' object when partial model or merged model fields are requested. This prevents confusing operations using the original object (ie. how do you save an object when it contains only 2 of 8 fields, plus maybe some fields from another model?).
If you print_r the object, and give me an indication of how that looks ... it might be just what you want.
I know this is an old question, but i found maybe easier solution:
$sale_stock = ORM::factory('product_type')
->where( 'product_type_id','=', $id )
->find_all();
die($sale_stock->stock);