var result = table1.Join(table2, o => o.ProgramID, t => t.ProgramID, (o, t) => new { o.ProgramID, t.Program })
.OrderBy(t => t.Program)
.Distinct();
the above linq statement actually returns the correct result, but he sql generated (below) is not as simple as it could be
SELECT [t2].[ProgramID], [t2].[Program]
FROM (
SELECT DISTINCT [t0].[ProgramID], [t1].[Program]
FROM [table1] AS [t0]
INNER JOIN [table2] AS [t1] ON [t0].[ProgramID] = [t1].[ProgramID]
) AS [t2]
ORDER BY [t2].[Program]
I would have thought the sql below is far cleaner but I'm not sure of the linq statement to achieve it.
select distinct
o.ProgramID,
t.Program
from
table1 0
inner join table2 t on t.ProgramID = o.ProgramID
order by t.Program
Thanks in advance
I don't know if it will help, but you can try something like this;
var result = (from o in table1
join t in table2 on o.ProgramID equals t.ProgramID
orderby t.Program
select new { o.ProgramID, t.Program }).Distinct();
I tried this and that works:
var result = (from o in table1
join t in table2 on o.ProgramID equals t.ProgramID
select new { o.ProgramID, t.Program })
.Distinct().OrderBy(t => t.Program)
.ThenBy(t => t.ProgramName)
.ThenBy(t => t.Description);
First you do Distinct and then OrderBy, then OrderBy works.
Profile the two queries, comparing stats-IO and the actual execution plan. It is entirely possible that it makes zero difference to the SQL server.
If you really want known TSQL, use ExecuteQuery-of-T and pass in the TSQL yourself. Maybe include some lock hints too (most commonly: NOLOCK)
Related
I try to realize this query from T-SQL in Linq to SQL:
Select * from RPG r
join RPGPlayer e on r.RPGID = e.RPGID
join [User] i on e.UserID = i.UserID
where i.Username like '%Dunkel%'
The result is correct for 2 Rows on SQL-Query itself.
I try this:
rpgList.Where(y => y.RPGPlayers == y.RPGPlayers.Where(e => e.User.Username.Contains(player))).ToList();
(rpgList is a list of the complete table loaded before)
Not entirely sure regarding the question, but the following is my attempt to represent the SQL join statement in LINQ …
from r in RPG
join e in RPGPlayer on r.RPGID equals e.RPGID
join i in User on e.UserID equals i.UserID
where i.Username.Contains("Dunkel")
I am trying to convert a ASP.NET project to Entity framework. How to re-write the following query to its LINQ equivalent?
SELECT {Table1 objects}
FROM [Table1] tb1
INNER JOIN [Table2] tb2
ON tb1.Table1ID = tb2.fk_Table1ID
WHERE tb2.fk_attrib1 = '123' AND tb2.fk_attrb2 = '345'
ORDER BY tb1.attrib1
The result is a collection of Table1 objects.
Here Table1 and Table2 correspond to object System.Data.Objects.ObjectSet of ADO.NET Entity Framework.
var results = from tb1 in Context.Table1
join tb2 in Context.Table2 on tb1.Table1ID == tb2.fk_Table1ID
where tb2.fk_attrib1 == "123" && tb2.fk_attrb2 == "345"
orderby tb1.attrib1
select tb1;
Something like this:
context.Table1
.Where( o => o.Table2s.Any( o2 =>
o2.fk_attrib1 == '123' &&
o2.fk_attrib2 == '345' ) )
.OrderBy( o => o.attrib1 )
.ToList();
BTW, LINQPad is great for trying out L2E queries.
This should help you a little bit. I suppose the main problem is with JOIN clause - in EF you can use NavigationProperties and don't need to worry about joining tables - EF will take care of that for you.
Also you are trying to filter on column from joined table. This you can do using Any method to find all Table1 elements that are connected to Table2 where those referenced elements have certain properties/columns. You should also get familiar with All method, as it might be useful to you in future.
from t1 in context.Table1
where t1.Table2s.Any(t2.fk_attrib1 == "123" && t2 => t2.fk_attrb2 == "345")
order by t1.attrib1
select t1;
Edit:
I assume that there is 1:n relationship between Table1 and Table2 which results in enumerable collection as NavigationProperty in Table1 objects.
Edit2:
Fixed error in code - didn't noticed that both attributes are from Table2 not Table1
Should be something like this:
var result = (from tb1 in Table1
from tb2 in Table2
where tb1.Key == tb2.Key &&
tb2.fk_attrib1 = '123' &&
tb2.fk_attrb2 = '345'
select ione).OrderBy(p=>p.attrib1);
Hope this helps.
I was working with the first method below, but then I found the second and want to know the difference and which is best.
What is the difference between:
from a in this.dataContext.reglements
join b in this.dataContext.Clients on a.Id_client equals b.Id
select...
and
from a in this.dataContext.reglements
from b in this.dataContext.Clients
where a.Id_client == b.Id
select...
I created a test case to test out the difference, and in your scenerio it turns out they are the same.
My test example used AdventureWorks but basically there is an association between
Products->CategoryId->Categories
var q = (
from p in Products
from c in Categories
where p.CategoryID==c.CategoryID
select p
);
q.ToList();
Produces this SQL:
SELECT [t0].[ProductID], [t0].[ProductName], [t0].[CategoryID]
FROM [Products] AS [t0], [Categories] AS [t1]
WHERE [t0].[CategoryID] = ([t1].[CategoryID])
var q2 = (
from p in Products
join c in Categories
on p.CategoryID equals c.CategoryID
select p);
q2.ToList();
Produces this sql:
SELECT [t0].[ProductID], [t0].[ProductName], [t0].[CategoryID]
FROM [Products] AS [t0]
INNER JOIN [Categories] AS [t1] ON [t0].[CategoryID] = ([t1].[CategoryID])
The difference between these two syntaxes will be in the way they are translated into SQL. You can trace Entity Framework or LINQ to SQL to determine the SQL:
LINQ to SQL: http://www.reflectionit.nl/Blog/PermaLinkcba15978-c792-44c9-aff2-26dbcc0da81e.aspx
Check the resulting SQL to determine if there are any differences that could affect performance.
I am trying to create query which orders by child collection's property. It is quite easy in SQL:
Select Table1.*
From Table1
Inner join Table2 on Table1.Id = Table2.Table1Id
OrderBy Table1.Column1, Table2.Column1
Here is how I did it in NHibernate 2 and it worked fine:
var result = Session.Linq<Table1>()
.OrderBy(x => x.Column1)
.ThenBy(x => x.Table2.FirstOrDefault().Column1);
After migrating to NHibernate 3 this doesn't work anymore. It throws NHibernate.Hql.Ast.ANTLR.QuerySyntaxException: Antlr.Runtime.NoViableAltException.
I am using NHibernate 3.1. Are there other solutions for such query?
The two queries aren't the same. The LINQ version (roughly) equates to:
SELECT Table1.*
FROM Table1
INNER JOIN (SELECT TOP 1 * FROM Table2 WHERE Table2.Table1ID = Table1.Id) AS FirstTable2
ORDER BY Table1.Colum1, FirstTable2.Table2
EDIT
If you want to replicate the original sql you might want something like:
Session.Linq<Table1>()
.SelectMany(t1 => t1.Table2, (t1,t2) => new { t1, t2 })
.OrderBy(t1t2 => t1t2.t1.Column1)
.ThenBy(t1t2 => t1t2.t2.Column2)
.Select(t1t2 => t1)
We have the following test model in the dbml file:
Model http://www.freeimagehosting.net/uploads/a86582498a.gif
For the test case there are 4 records in the table, 1 parent, 3 children. We are looking for the siblings of a specific record, including the specific record.
using (var db = new TestDataContext())
{
var query =
from f in db.Foos
where f.Name == "Two"
select f.Foo1.Foos; // get the record's parent's children
var foos = query.SelectMany(f => f); // project the EntitySet
Assert.AreEqual(3, foos.Count()); // passes
}
This returns the correct items with the following SQL:
SELECT [t2].[FooId],
[t2].[ParentFooId],
[t2].[Name]
FROM [dbo].[Foos] AS [t0]
INNER JOIN [dbo].[Foos] AS [t1] ON [t1].[FooId] = [t0].[ParentFooId]
CROSS JOIN [dbo].[Foos] AS [t2]
WHERE ([t0].[Name] = #p0)
AND ([t2].[ParentFooId] = [t1].[FooId])
We are wondering about the CROSS JOIN, this apparently is the result of the SelectMany?
Is there another way we should approach this in order to not have the CROSS JOIN?
You can stack from statements in a Linq query and that will probably help you out here.
var query = from f in db.Foos
from f2 in f.Foos
where f.Name == "Two"
select f2;
Which produces.
SELECT [t1].[FooId],
[t1].[Name],
[t1].[ParentFooId]
FROM [dbo].[Foos] AS [t0], [dbo].[Foos] AS [t1]
WHERE ([t0].[Name] = #p0) AND ([t1].[ParentFooId] = [t0].[FooId])
You could alternatively do:
var query = from f in db.Foos
where (from fo in db.Foos
where fo.Name == "Two"
select fo.ParentId).Contains(f.ParentId)
select f;
This should result in something like:
SELECT [t1].[FooId],
[t1].[ParentFooId],
[t1].[Name]
FROM [dbo].[Foos] AS [t1]
WHERE [t1].[ParentFooId] IN (SELECT [t0].[ParentFooId]
FROM [dbo].[Foos] AS [t0]
WHERE[t0].[Name] = #p0)
May differ a bit (possibly an Exists()depending on your model)...I don't have a profiler window handy.
Try this:
var siblings = DataContext.Foos.Where(a => a.FooID == 3)
.Select(b => Foos.Where(b => Foos.ParentFooID == a.ParentFooID));
Assert.AreEqual(3, siblings.Count());