when i execute this code
Dim lstOrders = (From oRR In dbO.orders
Where oRR.datum = werkdatum And oRR.status >= 40).ToList
Dim lstOrderRegels = (From ord In lstOrders
Join ordreg In dbO.orderregels On ord.ID Equals ordreg.ordernummer
Group Join a In dbO.artikelen On ordreg.artikelID Equals a.ID Into resultArt = Group
From art In resultArt.DefaultIfEmpty(New artikelen With {.ID = 0, .subgroep = 0})
Group Join subgr In dbO.productsubgroep On art.subgroep Equals subgr.ID Into result = Group
From sgr In result.DefaultIfEmpty(New productsubgroep With {.ID = 0, .productgroep_ID = 0})
Group Join hgr In dbO.productgroep On sgr.productgroep_ID Equals hgr.ID Into result2 = Group
From hg In result2.DefaultIfEmpty(New productgroep With {.ID = 0})
Join ses In dbO.sessie On ord.sessieID Equals ses.ID
Order By hg.code, sgr.code).ToList
i get a system out of memory execption.. First i though it could be the null value in one of the columns but even changing it to 0 it did not help. That second query should return around 4k result.
Related
I've got 2 datatables and am trying to summarize the data in them using a left outer join. The join works fine with this code
Dim Journal = From entries In dt.AsEnumerable()
Join inccodes In dtGL.AsEnumerable()
On entries.Field(Of String)("GLCode") Equals inccodes.Field(Of String)("GLCode")
Group By keys = New With {Key .IncomeCode = entries.Field(Of String)("GLCode"), Key .IncomeDesc = .inccodes.Field(Of String)("GLCodeDesc")}
Into ChargeSum = Group, sm = Sum(entries.Field(Of Decimal)("Amount"))
Where sm <> 0
Select New GL_Journal With {.IncomeCode = keys.IncomeCode, .IncomeDesc = keys.IncomeDesc, .LineAmount = sm}
`
However, since I really want a Left Outer Join I want to use Group Join instead of Join.
As soon as I change the Join to Group Join the code in the Group by at ".inccodes.field(Of String)("GLCodeDesc")" has ".inccodes" highlighted with the error "'inccodes' is not a member of 'anonymous type'"
I've reviewed much documentation on Group By and Group Join but there is scant information on them together.
Any ideas? Would I have more options/success with the method syntax?
If i try to reproduce your query using a left outer join, I will do something like this :
Dim dt As New DataTable
dt.Columns.Add("GLCode", GetType(String))
dt.Columns.Add("Amount", GetType(Decimal))
dt.Rows.Add("111", 3251.21)
dt.Rows.Add("222", 125.79)
dt.Rows.Add("999", 10000)
Dim dtGL As New DataTable
dtGL.Columns.Add("GLCode", GetType(String))
dtGL.Columns.Add("GLCodeDesc", GetType(String))
dtGL.Rows.Add("111", "a")
dtGL.Rows.Add("222", "b")
dtGL.Rows.Add("333", "c")
Dim Journal = From entries In dt.AsEnumerable()
Group Join inccodes In dtGL.AsEnumerable()
On entries.Field(Of String)("GLCode") Equals inccodes.Field(Of String)("GLCode")
Into Group
From lj In Group.DefaultIfEmpty()
Group By keys = New With {Key .IncomeCode = entries.Field(Of String)("GLCode"), Key .IncomeDesc = lj?.Field(Of String)("GLCodeDesc")}
Into ChargeSum = Group, sm = Sum(entries.Field(Of Decimal)("Amount"))
Select New With {.IncomeCode = keys.IncomeCode, .IncomeDesc = keys.IncomeDesc, .LineAmount = sm}
I would like to join 4 table, main table in this example is "MAGAZ101" (records on screen).
Table "TOWARY" keep name of items, unit of measurement(kg, quantity), itc.
Table "MAGAZ01" keep info about item in stock (1 in, 0 sold).
Table "PRZYTOW" keep info about how many same items had been take to stock also real weight of item.
Tables "MAGAZ101", "TOWARY", "MAGAZ01" are join by fields "TOWAR".
My problem is join "MAGAZ01" and "PRZYTOW" by column "DOK_PRZYJ", group and sum weight in "PRZYTOW" and also sum stock in "MAGAZ01", sum if item in table "MAGAZ01" is "1".
Here is my Code:
'''''''''
Dim MAGAZYNGLOWNY = (From tab1 In MAGAZ101.AsEnumerable()
Join tab2 In TOWARY.AsEnumerable() On tab1.Field(Of String)("TOWAR") Equals tab2.Field(Of String)("TOWAR")
Join tab3 In MAGAZ01.AsEnumerable() On tab1.Field(Of String)("TOWAR") Equals tab3.Field(Of String)("TOWAR")
Join tab4 In PRZYTOW.AsEnumerable() On tab3.Field(Of String)("DOK_PRZYJ") Equals tab4.Field(Of String)("DOK_PRZYJ")
Select New With {
.Symbol = tab1.Field(Of String)("TOWAR"),
.Nazwa = tab2.Field(Of String)("NAZWA"),
.Jm = tab2.Field(Of String)("JM"),
.Stan = If(IsDBNull(tab3.Item("STANMAG")), 0, tab3.Field(Of Double)("STANMAG")),
.WAGA = If(IsDBNull(tab4.Item("WAGA")), 0, tab4.Field(Of Double)("WAGA"))
}).ToList
Group and sum:
Dim MAGAZYNGLOWNYSUMA = (From A1 In MAGAZYNGLOWNY
Group A1 By Key = New With {.SYMBOL = A1.Symbol, .NAZWA = A1.Nazwa, .JM = A1.Jm, .STAN = A1.Stan, .Waga = A1.WAGA} Into Group
Select New With {
.Symbol = Key.SYMBOL,
.Nazwa = Key.NAZWA,
.Jm = Key.JM,
.Stan = Group.Sum(Function(A) A.Stan),
.WAGA = Group.Sum(Function(A) A.WAGA)
})
.Symbol - ID of item,
.Nazwa - name of item,
.Jm - unit,
.STAN - how many in stock,
.WAGA - weight,
Thanks in advace Adam
If you need, ask for detail.
Here is correct working code.
1st "MAG_GLOW" joined tables 1 and 2.
2nd "dane" joined tables 3 and 4, by "TOWAR" and also "DOK_PRZYJ" in the result the table is sorted and easy to sum.
3rd "Stock" where stock is greater than 0 (sum "STAN") and where stock is greater than 0 (sum weight "WAGA")
4th "MAGAZYNGLOWNY" joined 1st step "MAG_GLOW" and 3rd step "Stock".
Dim MAG_GLOW = (From tab1 In MAGAZ101.AsEnumerable()
Join tab2 In TOWARY.AsEnumerable() On tab1.Field(Of String)("TOWAR") Equals tab2.Field(Of String)("TOWAR")
Select New With {
.TOWAR = tab1.Field(Of String)("TOWAR"),
.Nazwa = tab2.Field(Of String)("NAZWA"),
.Jm = tab2.Field(Of String)("JM")
}).ToList
Dim dane = (From TAB3 In MAGAZ01.AsEnumerable()
Join TAB4 In PRZYTOW.AsEnumerable() On TAB3.Field(Of String)("towar") Equals TAB4.Field(Of String)("towar") And TAB3.Field(Of String)("Dok_przyj") Equals TAB4.Field(Of String)("Dok_przyj")
Select New With
{
.TOWAR = TAB3.Field(Of String)("TOWAR"),
.STAN = If(IsDBNull(TAB3.Item("STANMAG")), 0, TAB3.Field(Of Double)("STANMAG")),
.WAGA = If(IsDBNull(TAB4.Item("WAGA")), 0, TAB4.Field(Of Double)("WAGA"))
})
Dim stock = (From MAG In dane
Group MAG By TOWAR = MAG.TOWAR Into G = Group
Select New With {
.TOWAR = TOWAR,
.Stan = G.Where(Function(x) x.STAN > 0).Sum(Function(x) x.STAN),
.Waga = G.Where(Function(x) x.STAN > 0).Sum(Function(x) x.WAGA)
}
)
Dim MAGAZYNGLOWNY = (From tab1 In MAG_GLOW
Group Join tab2 In stock On tab2.TOWAR Equals tab1.TOWAR Into co = Group
From tab2 In co.DefaultIfEmpty()
Order By tab1.TOWAR
Select New With
{.TOWAR = tab1.TOWAR,
.NAZWA = tab1.Nazwa,
.Jm = tab1.Jm,
.STAN = If(IsNothing(tab2), Nothing, tab2.Stan),
.WAGA = If(IsNothing(tab2), Nothing, tab2.Waga)
})
I have 2 tables: pob (with results of some activities) and names (with user data). I try to select top 5 users from table pob based on their last activity date. So I inner join names and pob, then select top 5 users based on calculated max(date).
This query is working:
SELECT TOP 5
[u].[id],
[u].[name],
max([p].[date]) As LastDateOfUse,
FROM
[pob] [p]
INNER JOIN
[users] [u]
ON
[p].[id_name] = [u].[id]
WHERE
[p].[date] >= #2017-01-01#
GROUP BY
[u].[id],
[u].[name]
ORDER BY
max([p].[date]) DESC
Now I need to transform it into Linq query. This my attempt but it's not working.
"Key" is not a member of type "System.Collections.Generic.IEnumerable'1[VB$AnonymousType_2'2[pob,users]]".
Using db = New DbContext() With {.InlineParameters = True}
Dim query1 = From p In db.pob
Join u In db.users On p.id_name Equals u.id
Where p.date >= New Date(2017, 1, 1)
Group New With {p, u} By pu = New With {Key u.id, Key u.name} Into pg = Group
Select New RecentUser With
{
.id = pu.id,
.name = pu.name,
.LastDateOfUse = pg.Max(Function(f) f.p.date)
}
query1 = query1.OrderByDescending(Function(f) f.LastDateOfUse).Take(5)
Return query1.ToList
End Using
If I remove .LastDateOfUse = pg.Max(Function(f) f.p.Date) like below it works. By 'works' I mean there is no exception but of course result of query is wrong however grouping is done properly.
Using db = New DbContext() With {.InlineParameters = True}
Dim query1 = From p In db.pob
Join u In db.users On p.id_name Equals u.id
Where p.date >= New Date(2017, 1, 1)
Group New With {p, u} By pu = New With {Key u.id, Key u.name} Into pg = Group
Select New RecentUser With
{
.id = pu.id,
.name = pu.name
}
Return query1.ToList
End Using
Edit
I also tried going through navigation properties like below, but again I receive the same error.
Using db = New DbContext() With {.InlineParameters = True}
Dim query1 = From p In db.pob
Where p.date >= New Date(2017, 1, 1)
Group p By pu = New With {Key u.User.id, Key u.User.name} Into pg = Group
Select New RecentUser With
{
.id = pu.id,
.name = pu.name
.LastDateOfUse = pg.Max(Function(f) f.date)
}
query1 = query1.OrderByDescending(Function(f) f.LastDateOfUse).Take(5)
Return query1.ToList
End Using
And again if I remove .LastDateOfUse = pg.Max(Function(f) f.p.Date) like below it starts to work (proper grouping, wrong overall result).
Using db = New DbContext() With {.InlineParameters = True}
Dim query1 = From p In db.pob
Where p.date >= New Date(2017, 1, 1)
Group p By pu = New With {Key u.User.id, Key u.User.name} Into pg = Group
Select New RecentUser With
{
.id = pu.id,
.name = pu.name
}
Return query1.ToList
End Using
How can I transform above Sql query to Linq? (preferable answer in VB.Net but C# is ok too)
Solution
There is no solution yet. It looks like VB has bad Linq queries resolver - it creates unexpected method chain that can not be converted to SQL.
So instead
Group By ... Into pg = Group
we need
Group By ... Into LastDateOfUse = p.Max(Function(f) f.date).
See below full query.
Using db = New DbContext() With {.InlineParameters = True}
Dim query1 = From p In db.pob
Where p.date >= New Date(2017, 1, 1)
Group p By pu = New With {Key u.User.id, Key u.User.name} Into LastDateOfUse = p.Max(Function(f) f.date)
Select New RecentUser With
{
.id = pu.id,
.name = pu.name
.LastDateOfUse = LastDateOfUse
}
Return query1.ToList
End Using
Another problem with lambda syntax
Using lambda syntax we receive another exception.
Dim query = db.pob.
Where(Function(f) f.date >= New Date(2017, 1, 1).
GroupBy(Function(f) New With
{
Key .userid= f.user.id,
Key .username = f.user.name
}).Select(Function(f) New RecentUser With
{
.id = f.Key.userid,
.name = f.Key.username,
.LastDateOfUse = f.Max(Function(g) g.date)
}).ToList
Exception
VB.NET compiler adds unnecessary Convert to IEnumerable when generating Expression Tree.
An unhandled exception of type LinqToDB.Linq.LinqException occurred in linq2db.dll
Convert(f).Select(g => g.Date).Max() cannot be converted to SQL
GitHub
I posted an issue here.
Svyatoslav Danyliv based on my issue opened his own here.
I have to convert it to Linq in vb.net. I am new to sql to linq. Guidance welcomed
select CONVERT(VARCHAR(10),a.StartDt,112) datenew,
COUNT(distinct(b.EmployerAccountOid)) companymoved,
COUNT(distinct(c.EmployerAccountOid)) companyfailed,
COUNT(distinct(d.ProductAccountOid)) planmoved,
COUNT(distinct(e.ProductAccountOid)) planfailed
from ebp.MgnCOREDCDataGroupMigrationRun a
left join ebp.MgnCOREDCMigrationRun b
on a.MigrationRunID = b.MigrationRunID
And TypeCd = 1 and a.MigrationStatusCd = 4
left join ebp.MgnCOREDCMigrationRun c
on a.MigrationRunID = c.MigrationRunID
and TypeCd = 1 and a.MigrationStatusCd = 5
left join ebp.MgnCOREDCMigrationRun d
on a.MigrationRunID = d.MigrationRunID
and TypeCd = 2 and a.MigrationStatusCd = 4
left join ebp.MgnCOREDCMigrationRun e
on a.MigrationRunID = e.MigrationRunID
and TypeCd = 2 and a.MigrationStatusCd = 5
group by CONVERT(VARCHAR(10),a.StartDt,112)
I tried to convert it to Linq with fail.
Dim query1= (From migrationgroup In UnitOfWork.DbContext.Set( Of MgnCOREDCDataGroupMigrationRun)()
Group Join migration In UnitOfWork.Set(of MgnCOREDCMigrationRun)() On migrationgroup.MigrationRunID Equals migration.MigrationRunID And migrationgroup.TypeCode = 1 And migrationgroup.MigrationStatusCode=4 _
Into migrationErrorGrp = Group
From mgeg In migrationErrorGrp.DefaultIfEmpty()
Group Join migration1 In UnitOfWork.Set(of MgnCOREDCMigrationRun)() On migration1.MigrationRunID Equals migrationgroup.MigrationRunID And migrationgroup.TypeCode = 1 And migrationgroup.MigrationStatusCode=4 _
Into migrationErrorGrp1 = Group
From mgeg1 In migrationErrorGrp1.DefaultIfEmpty()
Group Join migration2 In UnitOfWork.Set(of MgnCOREDCMigrationRun)() On migration2.MigrationRunID Equals migrationgroup.MigrationRunID And migrationgroup.TypeCode = 2 And migrationgroup.MigrationStatusCode=5 _
Into migrationErrorGrp2 = Group
From mgeg2 In migrationErrorGrp2.DefaultIfEmpty()
Group Join migration3 In UnitOfWork.Set(of MgnCOREDCMigrationRun)() On migration3.MigrationRunID Equals migrationgroup.MigrationRunID And migrationgroup.TypeCode = 2 And migrationgroup.MigrationStatusCode=5 _
Into migrationErrorGrp3 = Group
From mgeg3 In migrationErrorGrp3.DefaultIfEmpty()
Group By CONVERT(VARCHAR(10),migrationgroup.StartDt,112) into g
select New With{CONVERT(VARCHAR(10),migrationgroup.StartDt,112),
Count(distinct(migration.EmployerAccountOid)) ,
Count(distinct(migration1.EmployerAccountOid)),
Count(distinct(migration2.EmployerAccountOid)),
Count(distinct(migration3.EmployerAccountOid))}).ToList()
If IsNothing(query1) Then
Return Nothing
End If
coredcmigrationhistory =
From coredcmigrationrow In query1()
My query is non-queryable. Can anybody guide me where I m goin wrong
I can't figure out that linq to entity query syntax. My problem is that if the value of the Calls table is null then noting comes up, I want to make something like a left join to get 'all' rows from the Calls table.
I tried to group it but I can't figure out the correct way to write it.
Dim TicketQuery As ObjectQuery = From c In EnData.Customer _
Join t In EnData.Calls On t.CustomerID Equals c.CustomerID _
Join Status In EnData.Lists On t.Status Equals Status.ListValue _
Join Project In EnData.Lists On t.Project Equals Project.ListValue _
Join Priorty In EnData.Lists On t.Priority Equals Priorty.ListValue _
Where c.Status > -1 And t.Status > -1 And Status.ListType = 1 And Project.ListType = 3 And Priorty.ListType = 2 _
Select New With {c.CustName, t.CallID, t.CallDate, t.CallTime, t.Description, Key .Status = Status.ListText, Key .Project = Project.ListText, t.DateModified, Key .Priority = Priorty.ListText}
How can I fix that?
Similar question: Linq to Sql: Multiple left outer joins
Microsoft Documentation: http://msdn.microsoft.com/en-us/library/bb918093.aspx#Y916
LINQ Examples from: http://msdn.microsoft.com/en-us/vbasic/bb737909
Left Outer Join
A so-called outer join can be expressed with a group join. A left outer joinis like a cross join, except that all the left hand side elements get included at least once, even if they don't match any right hand side elements. Note how Vegetables shows up in the output even though it has no matching products.
Public Sub Linq105()
Dim categories() = {"Beverages", "Condiments", "Vegetables", "Dairy Products", "Seafood"}
Dim productList = GetProductList()
Dim query = From c In categories _
Group Join p In productList On c Equals p.Category Into Group _
From p In Group.DefaultIfEmpty() _
Select Category = c, ProductName = If(p Is Nothing, "(No products)", p.ProductName)
For Each v In query
Console.WriteLine(v.ProductName + ": " + v.Category)
Next
End Sub
For left join in VB.net we can use Let
Dim q =
(From item In _userProfileRepository.Table
Let Country = (From p In _countryRepository.Table Where p.CountryId = item.CurrentLocationCountry Select p.Name).FirstOrDefault
Let State = (From p In _stateRepository.Table Where p.CountryId = item.CurrentLocationCountry Select p.Name).FirstOrDefault
Let City = (From p In _stateRepository.Table Where p.CountryId = item.CurrentLocationCountry Select p.Name).FirstOrDefault
Where item.UserId = item.ProfileId.ToString)
After the left join we can use group by
Dim q2 =
(From p In q Group p By p.Country, p.State, p.City Into Group
Select New With
{
.Country = Country,
.State = State,
.City = City,
.Count = Group.Count
}).ToList()