How to make a subquery using RQL (Raven Query Language)? - ravendb

I have this relationship between DB entities:
Entity1
- Name
...
Entity2
- Entity1FK
...
What I want to do is to query in RavenDB Studio using RQL all Entity2 which have Entity1 with according name.
This is a RQL query which is not valid but shows what I want to do:
from Entity2
where Entity1FK in (
from Entity1
where Name = "name"
select Id
)
I want to get all the IDs of Entity1 which have Name "name" and use these IDs in the same query. So, how to make the subquery in RQL? Was not able to find this in docs :(

What you want is the Related Documents concept:
Look at:
Create Related Documents
https://demo.ravendb.net/demos/csharp/related-documents/create-related-documents
Load Related Documents
https://demo.ravendb.net/demos/csharp/related-documents/load-related-documents
Query Related Documents
https://demo.ravendb.net/demos/csharp/related-documents/query-related-documents
You can access the data of an included document like this in RQL:
from "Orders" as o
load o.Company as c
select {
CompanyName: c.Name
}

Related

Matching Many To Many relation

I have the following entities:
#Entity
class User {
#ManyToMany(type => Group)
#JoinTable()
groups: Group[];
}
#Entity
class MediaObject {
#ManyToMany(type => Group)
#JoinTable()
groups: Group[];
}
#Entity
class Group {
// [...]
}
Now I want to select every MediaObject which has at least one group in common with the one specific User.
Example:
User 1 MediaObject 1
-----------------------------
Group 1 |--- Group 2
Group 2 ---| Group 3
User 1 has at least one same group as MediaObject
How can I build a where sql query for this? I use typeorm for building my queries, yet every sql query would help. Also, I want to understand how.
Typeorm joins the tables like this
LEFT JOIN "group" "groups" ON "groups"."id" = "media_groups"."groupId"
Using a simple JOIN you may retrieve MediaObject Id's that share at least one group with the user. Than use IN to retrieve the MediaObject's
select *
from MediaObject mo
where mo.id in
(
select moJoin.mediaObjectId
from media_object_groups_group moJoin
join user_groups_group uJoin on moJoin.groupId = uJoin.groupId
where uJoin.userId = 1
)
If there can be multiple overlapping groups between same MediaObject and the same User, an EXISTS semi-join might be faster than using IN:
SELECT m.*
FROM "MediaObject" m
WHERE EXISTS (
SELECT -- select list can be empty here
FROM user_groups_group gu
JOIN media_object_groups_group gm USING ("groupId")
WHERE gu."userId" = 1
AND gm."mediaObjectId" = m.id
);
Else, Radim's query should serve just fine after adding some double-quotes.
This assumes that referential integrity is enforced with foreign key constraints, so it's safe to rely on user_groups_group."userId" without checking the corresponding user even exists.
It's unwise to use reserved words like "user" or "group" or CaMeL-case strings as identifiers. Either requires double-quoting. ORMs regularly serve poorly in this respect. See:
Are PostgreSQL column names case-sensitive?

Databindings.Add() joined tabels with duplicate field names

I have two tables (Person and Company). Both tables have a field 'Id' (e.g. Person.Id and Company.Id) and the tables are joined on Person.CompanyId = Company.Id
When using DataBindings.Add() to a textbox for example - using WinForms and VB .Net - I would like to use method suggested by Microsoft namely:
txtPersonId.DataBindings.Add("Text", objDataView, "Person.Id")
txtCompanyId.DataBindings.Add("Text", objDataView, "Company.Id")
In this case, I get the following error however: "Child list for field Person cannot be created". After some fiddling around, it looks like 'Person' is looked up as a field in objDataSet instead of 'Person.Id'.
After I change the SQL query and have Person.Id returned as the alias 'PersonId' and Company.Id as 'CompanyId' the following code does work:
txtPersonId.DataBindings.Add("Text", objDataView, "PersonId")
txtCompanyId.DataBindings.Add("Text", objDataView, "CompanyId")
My question is therefor: Why is the Microsoft example not working here (see example here) and how can one include the table name in a DataBindings.Add() method otherwise?

SQL - Visual Studio - fill table if related data is empty

In my data source "Properties" is linked to "tenants" and I want to fill a table using a SQL query where tenant does not exist for that property.
In other words, "where that property is vacant."
What is the SQL statement for something like this?
SELECT tblProperties.Type, tblProperties.PropertyID, tblProperties.Street, tblProperties.Unit, tblProperties.City, tblProperties.State, tblProperties.Zip, tblProperties.Description, tblTenant.TenantID
FROM dbo.tblProperties
JOIN tblTenant
ON tblProperties.PropertyID = tblTenant.PropertyID
WHERE tblTenant.TenantID = ''
Properties and Tenants are both tables in your database?
Are they joined by a cross-reference table or...? It would be helpful to see the table structures.
Assuming that's the case, you just want something like:
SELECT * FROM Properties
WHERE PropertyId NOT IN
(SELECT PropertyId FROM PropertyTenants)
Try something like this:
SELECT Property.PropertyID, Property.TenantID
FROM Property LEFT JOIN Tenant ON Property.[TenantID] = Tenant.[TenantID]
WHERE (((Tenant.TenantID) Is Null));
This should show what properties don't have Tenants, Suggest you first try it with JUST the id fields, then add in the other fields later to keep the query simple and help with troubleshooting. If you have the potential to have multiple tenants who have offices in more than one property, this is a many-to-many relationship that is best documented in an index table.

SQL subquery result in LINQ and Entity Framework Code First

I want to make a query that'll return me entities and additionally a number of one of their associated entities. For example:
select *, (select COUNT(*) from Forms where Contact_Id = Contacts.Id)
as FormsCount from Contacts;
My Contact entity has a property named FormsCount, but it isn't mapped since there's no column named like that in the table. Is it possible to write one LINQ query that'll return me Contact entities with the additional FormsCount property filled in?
Alternatively, I'd be happy if I could get the FormsCount values in a separate field and I can copy them to the entities manually. The result from the query could be in this form for example:
{
Contact Contact;
int FormsCount;
}
Then I can iterate over the results and copy FormsCount to Contact. Maybe this can be achieved by using projections?
I know how to do that using 2 queries:
a) fetch contact entities first
b) fetch pairs or contact ID and FormsCount for contacts returned in the first query.
But I'd like to do that using one query. Also, I don't want the FormsCount property to be always filled in my Contact entity, I want to have a control over that. Any ideas?
Thanks,
Michal
You are right about the projection.
If Contact has a navigation property Forms you can project:
from c in context.Contacts
select new { Contact = c, FormsCount = c.Forms.Count() }
If not, you'll have to use a subquery:
from c in context.Contacts
select new
{
Contact = c,
FormsCount = context.Forms.Count(f => f.Contact_Id == c.Id)
}
EF will handle both situations in one SQL query.

hibernate define class from multiple columns in multiple tables

i have a class with some datafields:
class Call{
roomId
roomDisplay
roomLocation
typeId
name
staffAidId
}
now i would like to map this using hibernate annotations in java
but the original sql query that i used was something like this:
SELECT
c.roomId,
r.display,
r.location,
c.typeId,
c.staffAidId,
s.firstname,
s.lastname
FROM callalert c
JOIN staffmember s
LEFT JOIN roomGroup g ON g.groupId = s.roomGroupId
LEFT JOIN room r ON r.roomId = g.roomId
WHERE s.staffId = 4444 AND c.roomId = g.roomId
is there a way to map this
in other words:
is there a way to map columns from different tables to 1 custom class?
the class is no direct representation of 1 table
and from all the tables that are involved, not all columns are used
edit
I tried the view solution:
created a view with the above query
then I try to generate the hibernate classes using Netbeans
and I generates 2 classes:
the class Calls and an Embeddable class CallId
after searching the Internet this happens because hibernate needs a primary key so it creates one himself
how can I make sure only 1 class gets generated?
how do I give a view a primary key (a good primary key would be 1 of the primary keys of the underlying tables). how do i set this?
You should be able to do that if you create a database view for that query. It would work, but it has the downside that you can't auto-generate the ddl schema from the database models.
Check out this article