Nested select not working in NHibernate.Linq - nhibernate

I want to load the list of users and their roles, with this query:
var q = from u in session.Linq<User>()
select new
{
u.Name,
u.Password,
Roles = from r in u.Roles
select new { r.Code, r.Name }
};
But this query is not working.
Produce the following error: "The method 'Select' is not implemented."
¿The message suggest that NHibernate.Linq not support nested selects?
I want to know if this is certain or exist other way to do this?
PD: please excuse my bad english.

Current implementation of Linq provider is based on CriteriaApi and that why it can create only simple queries

Related

SQL Postgre to show 1 data if get same some multiple data and how to implement to laravel query

i want to ask about sql in postgresql, i got data from join with 3 table, i got the result but i got multiple data like this image
result
and here my sql code in postgresql
select users.* from users inner join model_has_roles on model_has_roles.model_id = users.id
left join roles on roles.id = model_has_roles.role_id where roles.name not in ('job-seeker') order by users.name asc
how to fix this query where i got the multiple data only 1 data to show.
and i want this sql to implement to laravel query and here my code now
public function getAccountList(){
$req = app(Request::class);
// $getAccount = User::query();
$getAccount = User::join('model_has_roles', function($join) {
$join->on('users.id', '=', 'model_has_roles.model_id');
})->leftJoin('roles', function($join){
$join->on('model_has_roles.role_id', '=', 'roles.id');
});
$getAccount->whereNotIn('roles.name', ['job-seeker']);
if ($q = $req->query('q')) {
$searchTerm = trim(strtolower($q));
$getAccount->whereRaw(
'LOWER(users.name) like (?) or LOWER(users.email) like (?)',
["%{$searchTerm}%", "%{$searchTerm}%"]
);
}
// $getAccount->get()->unique('name');
$getAccount->select(['users.*']);
$paginator = $this->pagination($getAccount);
return $this->paginate($paginator, new UserTransformer);
}
how to fix the query only 1 data to show not the multiple same data. thank you for helping me. God Bless You
use distinct()
$data = DB::table('test')->[your query builder]->distinct()->get();
Laravel Query Builder Docs
Just change a bit to make it related to your query builder

How to change Doctrine "findBy/findOneBy" functions's behaviors to reduce the number of queries?

I'm working on a Symfony2 using Doctrine.
I would like to know how to change the behavior of "findBy" functions when retrieving my entities.
For example, if you call "findAll()", it returns all products.
$entities = $em->getRepository('ShopBundle:Product')->findAll();
However, how to reduce the number of queries, because, by default, it will create a new query each time I want to get a member linked to a join column. So if I get 100 entities, it will process 101 queries (1 to get all entities and 1 by entity to get join column).
So today, I use createQuery() function by specifying the joins. Is there a way to configure something about findBy functions to skip createQuery method ?
Thanks in advance !
K4
You can fetch out this in below way
public function findUser() {
$query = $this->getEntityManager()
->createQuery('SELECT us.id as id, us.name as user_name FROM Bundle:User us');
try {
return $query->getResult();
} catch (\Doctrine\ORM\NoResultException $e) {
return null;
}
}

Creating a Rails 3 scope that joins to a subquery

First off, I'm a Ruby/Rails newbie, so I apologize if this question is basic.
I've got a DB that (among other things) looks like this:
organizations { id, name, current_survey_id }
surveys { id, organization_id }
responses { id, survey_id, question_response_integer }
I'm trying to create a scope method that adds the average of the current survey answers to a passed-in Organization relation. In other words, the scope that's getting passed into the method would generate SQL that looks like more-or-less like this:
select * from organizations
And I'd like the scope, after it gets processed by my lambda, to generate SQL that looks like this:
select o.id, o.name, cs.average_responses
from organizations o join
(select r.id, avg(r.question_response_integer) as average_responses
from responses r
group by r.id) cs on cs.id = o.current_survey_id
The best I've got is something like this:
current_survey_average: lambda do |scope, sort_direction|
average_answers = Responses.
select("survey_id, avg(question_response_integer) as average_responses").
group("survey_id")
scope.joins(average_answers).order("average_responses #{sort_direction}")
end
That's mostly just a stab in the dark - among other things, it doesn't specify how the scope could be expected to join to average_answers - but I haven't been able to find any documentation about how to do that sort of join, and I'm running out of things to try.
Any suggestions?
EDIT: Thanks to Sean Hill for the answer. Just to have it on record, here's the code I ended up going with:
current_survey_average: lambda do |scope, sort_direction|
scope_table = scope.arel.froms.first.name
query = <<-QUERY
inner join (
select r.survey_id, avg(r.question_response_integer) as average_responses
from responses r
group by r.survey_id
) cs
on cs.survey_id = #{scope_table}.current_survey_id
QUERY
scope.
joins(query).
order("cs.average_responses #{sort_direction}")
end
That said, I can see the benefit of putting the averaged_answers scope directly onto the Responses class - so I may end up doing that.
I have not been able to test this, but I think the following would work, either as-is or with a little tweaking.
class Response < ActiveRecord::Base
scope :averaged, -> { select('r.id, avg(r.question_response_integer) as average_responses').group('r.id') }
scope :current_survey_average, ->(incoming_scope, sort_direction) do
scope_table = incoming_scope.arel.froms.first.name
query = <<-QUERY
INNER JOIN ( #{Arel.sql(averaged.to_sql)} ) cs
ON cs.id = #{scope_table}.current_survey_id
QUERY
incoming_scope.joins(query).order("average_responses #{sort_direction}")
end
end
So what I've done here is that I have split out the inner query into another scope called averaged. Since you do not know which table the incoming scope in current_survey_average is coming from, I got the scope table name via scope.arel.froms.first.name. Then I created a query string that uses the averaged scope and joined it using the scope_table variable. The rest is pretty self-explanatory.
If you do know that the incoming scope will always be from the organizations table, then you don't need the extra scope_table variable. You can just hardcode it into the join query string.
I would make one suggestion. If you do not have control over sort_direction, then I would not directly input that into the order string.

How to simplify this LINQ to Entities Query to make a less horrible SQL statement from it? (contains Distinct,GroupBy and Count)

I have this SQL expression:
SELECT Musclegroups.Name, COUNT(DISTINCT Workouts.WorkoutID) AS Expr1
FROM Workouts INNER JOIN
Series ON Workouts.WorkoutID = Series.WorkoutID INNER JOIN
Exercises ON Series.ExerciseID = Exercises.ExerciseID INNER JOIN
Musclegroups ON Musclegroups.MusclegroupID = Exercises.MusclegroupID
GROUP BY Musclegroups.Name
Since Im working on a project which uses EF in a WCF Ria LinqToEntitiesDomainService, I have to query this with LINQ (If this isn't a must then pls inform me).
I made this expression:
var WorkoutCountPerMusclegroup = (from s in ObjectContext.Series1
join w in ObjectContext.Workouts on s.WorkoutID equals w.WorkoutID
where w.UserID.Equals(userid) && w.Type.Equals("WeightLifting")
group s by s.Exercise.Musclegroup into g
select new StringKeyIntValuePair
{
TestID = g.Select(n => n.Exercise.MusclegroupID).FirstOrDefault(),
Key = g.Select(n => n.Exercise.Musclegroup.Name).FirstOrDefault(),
Value = g.Select(n => n.WorkoutID).Distinct().Count()
});
The StringKeyIntValuePair is just a custom Entity type I made so I can send down the info to the Silverlight client. Also this is why I need to set an "TestID" for it, as it is an entity and it needs one.
And the problem is, that this linq query produces this horrible SQL statement:
http://pastebay.com/144532
I suppose there is a better way to query this information, a better linq expression maybe. Or is it possible to just query with plain SQL somehow?
EDIT:
I realized that the TestID is unnecessary because the other property named "Key" (the one on which Im grouping) becomes the key of the group, so it will be a key also. And after this, my query looks like this:
var WorkoutCountPerMusclegroup = (from s in ObjectContext.Series1
join w in ObjectContext.Workouts on s.WorkoutID equals w.WorkoutID
where w.UserID.Equals(userid) && w.Type.Equals("WeightLifting")
group w.WorkoutID by s.Exercise.Musclegroup.Name into g
select new StringKeyIntValuePair
{
Key = g.Key,
Value = g.Select(n => n).Distinct().Count()
});
This produces the following SQL: http://pastebay.com/144545
This seems far better then the previous sql statement of the half-baked linq query.
But is this good enough? Or this is the boundary of LinqToEntities capabilities, and if I want even more clear sql, I should make another DomainService which operates with LinqToSQL or something else?
Or the best way would be using a stored procedure, that returns Rowsets? If so, is there a best practice to do this asynchronously, like a simple WCF Ria DomainService query?
I would like to know best practices as well.
Compiling of lambda expression linq can take a lot of time (3–30s), especially using group by and then FirstOrDefault (for left inner joins meaning only taking values from the first row in the group).
The generated sql excecution might not be that bad but the compilation using DbContext which cannot be precompiled with .NET 4.0.
As an example 1 something like:
var q = from a in DbContext.A
join b ... into bb from b in bb.DefaultIfEmtpy()
group new { a, b } by new { ... } into g
select new
{
g.Key.Name1
g.Sum(p => p.b.Salary)
g.FirstOrDefault().b.SomeDate
};
Each FirstOrDefault we added in one case caused +2s compile time which added up 3 times = 6s only to compile not load data (which takes less than 500ms). This basically destroys your application's usability. The user will be waiting many times for no reason.
The only way we found so far to speed up the compilation is to mix lambda expression with object expression (might not be the correct notation).
Example 2: refactoring of previous example 1.
var q = (from a in DbContext.A
join b ... into bb from b in bb.DefaultIfEmtpy()
select new { a, b })
.GroupBy(p => new { ... })
.Select(g => new
{
g.Key.Name1
g.Sum(p => p.b.Salary)
g.FirstOrDefault().b.SomeDate
});
The above example did compile a lot faster than example 1 in our case but still not fast enough so the only solution for us in response-critical areas is to revert to native SQL (to Entities) or using views or stored procedures (in our case Oracle PL/SQL).
Once we have time we are going to test if precompilation works in .NET 4.5 and/or .NET 5.0 for DbContext.
Hope this helps and we can get other solutions.

Simple Linq question: How to select more than one column?

my code is:
List<Benutzer> users = (from a in dc.Benutzer
select a).ToList();
I need this code but I only want to select 3 of the 20 Columns in the "Benutzer"-Table.
What is the syntax for that?
Here's a query expression:
var users = (from a in dc.Benutzer
select new { a.Name, a.Age, a.Occupation }).ToList();
Or in dot notation:
var users = dc.Benutzer.Select(a => new { a.Name, a.Age, a.Occupation })
.ToList();
Note that this returns a list of an anonymous type rather than instances of Benutzer. Personally I prefer this approach over creating a list of partially populated instances, as then anyone dealing with the partial instances needs to check whether they came from to find out what will really be there.
EDIT: If you really want to build instances of Benutzer, and LINQ isn't letting you do so in a query (I'm not sure why) you could always do:
List<Benutzer> users = dc.Benutzer
.Select(a => new { a.Name, a.Age, a.Occupation })
.AsEnumerable() // Forces the rest of the query to execute locally
.Select(x => new Benutzer { Name = x.Name, Age = x.Age,
Occupation = x.Occupation })
.ToList();
i.e. use the anonymous type just as a DTO. Note that the returned Benutzer objects won't be associated with a context though.
List<Benutzer> users = (from a in dc.Benutzer
select new Benutzer{
myCol= a.myCol,
myCol2 = a.myCol2
}).ToList();
I think that's what you want if you want to make the same kind of list. But that assumes that the properties you are setting have public setters.
try:
var list = (from a in dc.Benutzer select new {a.Col1, a.Col2, a.Col3}).ToList();
but now you have list of anonymous object not of Benutzer objects.