Can you do an inner select with Subsonic? - c#

This is my sql query: subsonic version 2.1.0.0 No Linq (.net 2.0)
select
(
select Title from MenuTranslation mnu2 where
mnu2.languageid = 1 and mnu2.menuelementid = menutranslation.menuelementid
)as BaseTitle, *
from menutranslation
inner join menuelement on menuelement.id = menutranslation.menuelementid
where menuelementid
in (select id from menuelement where parentid = 4)
and languageid = 2

Not at this time - however you can run IN queries with a SELECT - not subqueries however.

You would need to use the inlineQuery class where you generate the sql yourself to accomplish what you are going after

Related

SQL query distinct issue

I have written the below query to list all the rows in table [HRSurvey]
which empid is only present in empsurveyselection. Both table have empid columns.
But i am not able to get the proper results because there
might be multiple empid for same surveyid in empsurveyselection table.
But this query works fine when there is only one empid for each surveyid in empsurveyselection table.
Could you please rewrite the query to list the all the rows in the table HRSurvey where the empid are there in empsurveyselection ?
SELECT hrs.*
FROM [HRSurvey] hrs
Left Join [HRSurveyEmployee] hse
ON hse.EmpID = hrs.EmpID
LEFT Join Surveys s
ON s.surveyid = hse.surveyid
WHERE hrs.empid IN (
SELECT empid FROM [HRSurveyEmployee] where surveyid = s.surveyid
) and sempid
in ( select DISTINCT empid FROM empsurveyselection WHERE deptid=9 and surveyid = s.surveyid)
You can write as:
SELECT hrs.col1, -- Worst Practice to use * in production code to pull data
hrs.col12 -- Use explicit column names instead
FROM [HRSurvey] hrs
INNER JOIN [HRSurveyEmployee] hse ON hse.EmpID = hrs.EmpID
INNER JOIN [Surveys] s ON s.surveyid = hse.surveyid
INNER JOIN [empsurveyselection]ess ON ess.deptid=9
AND ess.surveyid = s.surveyid AND hrs.sempid = ess.empid
Please try with the below query....
select a.*
from HRSurvey a
where empid exists (select 1
from empsurveyselection b
where a.Empid = b.Empid)
Thanks for the help! Actually issue was not with the query. Issue was with the data and i fixed it.

Linq To entities, Select from select

I have tried for sum time now but I cant get the hold of doing this selection in LINQ to Entites? How can I do a Select on a Selection?
SELECT * FROM tProduct AS tpp, tProductGroupDetail AS tppg,
(SELECT tpgd.ProductGroupID AS pgID
FROM tProduct AS tp, tProductGroupDetail AS tpgd
WHERE tp.ProductID = 428 AND tpgd.ProductID = tp.ProductID) AS JoinedTable
WHERE JoinedTable.pgID = tppg.ProductGroupID
AND tpp.ProductID = tppg.ProductGroupID
Your SQL statement is very bizarre. Isn't it equivalent to the following statement?
SELECT *
FROM
tProduct AS p
INNER JOIN tProductGroupDetail AS pgd
ON p.ProductID = pgd.ProductGroupID
WHERE
pgd.ProductID = 428
The corresponding LINQ query would then be rather obvious.
Let's change your SQL step by step:
The nested SELECT looks like this:
(SELECT tpgd.ProductGroupID AS pgID
FROM tProduct AS tp, tProductGroupDetail AS tpgd
WHERE tp.ProductID = 428 AND tpgd.ProductID = tp.ProductID)
This is the same as
(SELECT tpgd.ProductGroupID AS pgID
FROM tProductGroupDetail AS tpgd
WHERE tpgd.ProductID = 428)
Since tpgd.ProductID = tp.ProductID you can directly directly test for tpgd.ProductID = 428 without having to join with tp. The simplyfied statement now looks like this:
SELECT * FROM tProduct AS tpp, tProductGroupDetail AS tppg,
(SELECT ProductGroupID
FROM tProductGroupDetail
WHERE ProductID = 428) AS JoinedTable
WHERE JoinedTable.ProductGroupID = tppg.ProductGroupID
AND tpp.ProductID = tppg.ProductGroupID
Basically, what it does, is to join tProduct with tProductGroupDetail. The purpose of the additional join with JoinedTable is to restrict the records to contain only product groups having a ProductID = 428. This condition can be applied directly:
SELECT *
FROM tProduct AS tpp, tProductGroupDetail AS tppg,
WHERE tppg.ProductID = 428 -- Note: ProductID of tggp, NOT tpp!
AND tpp.ProductID = tppg.ProductGroupID
The last step is to replace the join with an INNER JOIN clause and to tweak the aliases. This yields my first SQL statement.
To obtain the list of ProductGroup containing the product #428, just write:
dataContext.Products.FirstOrDefault(p => p.ProductID == 428).ProductGroups
This solution assumes the existence in the entity Product of the navigation property ProductGroups. If this is not the case, thank you to specify the entity model.
I think this should do it (although it's off the top of my head, not tested):
var product = Products.Where(x => x.ProductGroup.Any(y => y.ProductID == 428));

Common Table Expression in EntityFramework

I have this query in Sql Server which I need to consume in EntityFramework, So how can I write a EntityFramwork code which will have the same result as this
WITH cte AS
(
SELECT *
FROM StockGroups
WHERE GroupParent ='Stationery'
UNION ALL
SELECT g.*
FROM StockGroups g
JOIN cte
ON g.GroupParent = cte.GroupName
)
SELECT *
FROM cte
I don't know how to convert it in EF, so I tried with join.
from a in db.StockGroups
join b in db.StockGroups on new { GroupParent = a.GroupParent } equals new { GroupParent = b.GroupName }
where
b.GroupName == "Stationery"
select new {
a.GroupName,
a.GroupParent,
Column1 = b.GroupName,
Column2 = b.GroupParent
}
But the result is not same, as recursive as CTE.
EF does not support recursive CTE's. Use a view or a table valued function.
Getting input from the other experts over SO, I have come up with my own way to achieve this.
IEnumerable<StockGroup> sg = dbContext.ExecuteStoreQuery<StockGroup>(
#"WITH q AS
(
SELECT *
FROM LedgerGroups
WHERE GroupParent = 'Customers'
UNION ALL
SELECT m.*
FROM LedgerGroups m
JOIN q
ON m.GroupParent = q.GroupName
)
SELECT *
FROM q
");
You cannot use CTE recursion in Entity Framework.
Use stored procedure and call that stored procedure through EF
I dont think there is support for recursive CTEs in LINQ nor in EF. The solution is to expose the CTE as a view. The article on Recursive or hierarchical queries using EF Code First and Migrations shows how to deploy such a view using EF code first migrations. Recursive or hierarchical queries using EF Code First and Migrations
Original source:
https://stackoverflow.com/a/11929928/3850405

NHibernate Criteria engine with inner join and subquery

Is it posible in NHibernate to create a query that looks like this?
select hi.ContactId
From dbo.vw_HostInterests hi INNER JOIN
( Select cm1.ContactId
From dbo.vw_ContactMoments cm1 INNER JOIN
(
Select Contactid
From dbo.vw_ProfileNaw
where GenderId = 1000
) as pn1 on cm1.ContactId = pn1.ContactId
where cm1.ActivityId = 1001
)as cm on hi.ContactId = cm.ContactId
where hi.ActivityId = 1038
I've managed to create the correct output with the IN statement, but I'd realy like the SQL to look like this.
The Criteria below shows part of above query with the IN Statement I used (but want to replace):
ICriteria criteria = DbSession.CreateCriteria<Contact>();
var dCriteria1 = DetachedCriteria.For(typeof(VwHostInterest))
.Add(Expression.Eq("ActivityId", 1038))
.SetProjection(Projections.ProjectionList()
.Add(Projections.GroupProperty("ContactId")));
var dCriteria2 = DetachedCriteria.For(typeof(VwContactMoment))
.Add(Expression.Eq("ActivityId", 1001))
.SetProjection(Projections.ProjectionList()
.Add(Projections.GroupProperty("ContactId")));
criteria.Add(Subqueries.PropertyIn("ContactId", dCriteria1));
criteria.Add(Subqueries.PropertyIn("ContactId", dCriteria2));
int count = (Int32)criteria
.SetProjection(Projections.Count("ContactId"))
.UniqueResult();
Probably not the answer you are looking for and apologies if it isn't but my experience is that your best bet with such complex queries would be to:
a) Do this whole thing as a view and map it in NHibernate
b) Create the inner select as a view and create a mapping such that you can relate it in your query
b) Or override nhibernate (override as in skip and not in OO terms ;) and write this as a named query using native SQL.
Does that nested query produce the same result as the following?
SELECT hi.ContactId
FROM dbo.vw_HostInterests hi
INNER JOIN vw_ContactMoments cm1 on hi.ContactId = cm1.ContactId
AND cm1.ActivityId = 1001
INNER JOIN dbo.vw_ProfileNaw pn1 on pn1.ContactId = cm1.ContactId
AND pn1.GenderId = 1000
WHERE hi.ActivityId = 1038

LINQ to Entities find top records from ordered groupings

I have a problem that I know how to solve in SQL but not with Linq to Entities.
My data looks like this:
ID GROUP TIMESTAMP
-- ----- ---------
1 A 2011-06-20
2 A 2011-06-21
3 B 2011-06-21
4 B 2011-06-22
5 B 2011-06-23
6 C 2011-06-30
I want to retrieve all the Entity objects (not just the ID) such that I am only getting the most recent record from each group. (ie. the records with ids 2, 5, 6)
In SQL I would do something like this:
SELECT * FROM my_table a
WHERE a.timestamp =
(SELECT MAX(timestamp) FROM my_table b
WHERE a.group = b.group)
(For the sake of this question you can assume that timestamp is unique within each group).
I'd like to do this query against a WCF Data Service using Linq to Entities but I can't seem to have a nested query that references the outside query like this. Can anyone help?
Possibly not as clean and efficient as the hand written version but here's what I came up with
var q = from a in db.MyEntities
where a.Timestamp == (from b in db.MyEntities
where b.Group == a.Group
select b.Timestamp).Max()
select a;
which translates into this SQL
SELECT
[Project1].[Id] AS [Id],
[Project1].[Group] AS [Group],
[Project1].[Timestamp] AS [Timestamp]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Group] AS [Group],
[Extent1].[Timestamp] AS [Timestamp],
[SSQTAB1].[A1] AS [C1]
FROM [MyEntities] AS [Extent1]
OUTER APPLY
(SELECT
MAX([Extent2].[Timestamp]) AS [A1]
FROM [MyEntities] AS [Extent2]
WHERE [Extent2].[Group] = [Extent1].[Group]) AS [SSQTAB1]
) AS [Project1]
WHERE [Project1].[Timestamp] = [Project1].[C1]
Hi try to use linqer that will convert your sql statements to linq query.
Linqer
Best Regards
This should work:
var query = db.my_table
.GroupBy(p=>p.group)
.Select(p=>p.OrderByDescending(q=>q.timestamp).First());
Here you go.A simple way to do.
var result = (from x in my_table
group x by x.Group into g
select new
{
g.Key,
timestamp = g.Max(x => x.TimeStamp),
g //This will return everything in g
});

Categories