I am successfully using some linq to populate some variables but in order to make it more efficient I would like to avoid the current repetition when setting the variables nextMDTID, nextPatientID, nextCareID and nextMDTDate.
Can I create a variable to hold the data generated using the linq query and then re-use it to avoid the repetition?
Dim thisPTOrder = (From p In ThisMDTData Where p.MDTID = Request.QueryString("MDTID") Select p.PTOrder).FirstOrDefault
Dim nextPTOrder = thisPTOrder + 1
Dim d = ThisMDTData.Where(Function(p) p.PTOrder = nextPTOrder And p.PTOrder <= p.PTOrder)
Dim nextMDTID = (From p In ThisMDTData Where p.PTOrder = nextPTOrder And p.PTOrder <= p.MaxPTOrder Select p.MDTID).FirstOrDefault
Dim nextPatientID = (From p In ThisMDTData Where p.PTOrder = nextPTOrder And p.PTOrder <= p.MaxPTOrder Select p.PatientID).FirstOrDefault
Dim nextCareID = (From p In ThisMDTData Where p.PTOrder = nextPTOrder And p.PTOrder <= p.MaxPTOrder Select p.CareID).FirstOrDefault
Dim nextMDTDate = (From p In ThisMDTData Where p.PTOrder = nextPTOrder And p.PTOrder <= p.MaxPTOrder Select p.MDTDate).FirstOrDefault
Using a proper definition for d, you can simplify the results extraction:
Dim d = ThisMDTData.Where(Function(p) p.PTOrder = nextPTOrder And p.PTOrder <= p.MaxPTOrder).Select(Function(p) New With { p.MDTID, p.PatientID, p.CareID, p.MDTDate }).FirstOrDefault
Dim nextMDTID = d?.MDTID
Dim nextPatientID = d?.PatientID
Dim nextCareID = d?.CareID
Dim nextMDTDate = d?.MDTDate
Putting the Select/FirstOrDefault on the definition of d ensures that any database is only queried once for the minimally needed data. You could leave the Select off if the row size is small, or the row only has those four properties. You can use the obvious fluent query translation for d if desired.
NOTE: If you don't want some of the variables to be Nullable, use If:
Dim nextPatientID = If(d?.PatientID, CType(Nothing, Integer))
Related
I have two dataTables ,and i want select all rows from DataTable1 where id is not in DataTable2.below what i have tried :
Sql = "select *,N°Reçu as NumRecu from V_Sit_J_Vente,V_Bien where V_Sit_J_Vente.Code_bien=V_Bien.Code_bien and date_situation <= '" + dt2 + "' and date_situation >= '" + dt1 + "'"
Dim GlobalDataVente As DataTable = utilitaire.getDataSet(Sql).Tables(0)
Sql = "select * from V_Reserv_Annule"
Dim GlobalDataAnnule As DataTable = utilitaire.getDataSet(Sql).Tables(0)
Dim query = (From order In GlobalDataVente.AsEnumerable() _
Where order!code_projet = tab.Rows(i).Item("code_projet")).ToList
Dim bannedCCList = From c In GlobalDataAnnule.AsEnumerable() _
Where c!type.Equals("Transfert acompte") = False And c!date_annule <= dt2
Dim exceptBanned = From c In query Group Join b In bannedCCList On c.Field(Of String)("N°Reçu") Equals b.Field(Of String)("num_reserv_remplace")
Into j() From x In j.DefaultIfEmpty() Where x Is Nothing Select c
What i want that "exceptBanned " containt all rows of "query" except row exist in "bannedCCList "
Thanks in advance
You can use Contains for this:
Dim query = (From order In GlobalDataVente.AsEnumerable() _
Where order!code_projet = tab.Rows(i).Item("code_projet")).ToList
Dim bannedCCList = From c In GlobalDataAnnule.AsEnumerable() _
Where c.type.Equals("Transfert acompte") = False And c.date_annule <= dt2
Select c.Field(Of String)("num_reserv_remplace")
Dim exceptBanned = From c In query
Where Not bannedCCList.Contains(c.Field(Of String)("N°Reçu"))
Select c
bannedCCList defines a query that produces the Id values you want to exclude; exceptBanned combines query with this list of Ids into a query that only runs once to return the final results. It works this way because bannedCCList is an IEnumerable. It isn't executed when it's defined, only when it's actually used.
I have three dropdowns; the second one (Members) populates based on what's in the first (Units), and the third one (Customers) SHOULD populate based on what's in the second; but it doesn't.
Here's the query that works in LINQPad (returns a list of Company names):
select distinct companyname from customers C left join members M on M.MemberNo = C.MemberNo where M.MemberNo = '052' order by companyname
...but does not work in the following code:
'Populate the Members dropdown
Dim selectedUnit As String = DropDownListUnits.Text
Dim membersDT As DataTable
sql = "select distinct shortname, M.memberno from members M left join memberunitproducts mup on M.MemberNo = mup.MemberNo where unit = '" + selectedUnit + "' order by shortname"
retDS = sqlDAL.runSQLDataSet(sql)
membersDT = retDS.Tables(0)
DropDownListMembers.DataSource = membersDT
DropDownListMembers.DataTextField = "shortname"
DropDownListMembers.DataValueField = "memberno"
DropDownListMembers.DataBind()
'Populate the Customers dropdown
Dim selectedMember As String = DropDownListMembers.DataValueField
Dim customersDT As DataTable
sql = "select distinct companyname from customers C left join members M on M.MemberNo = C.MemberNo where M.MemberNo = '" + selectedMember + "' order by companyname"
retDS = sqlDAL.runSQLDataSet(sql)
customersDT = retDS.Tables(0)
DropDownListCustomers.DataSource = customersDT
DropDownListCustomers.DataTextField = "companyname"
DropDownListCustomers.DataValueField = "companyname"
DropDownListCustomers.DataBind()
The third (Customers) dropdown remains unpopulated when this runs - why?
It's probably not needed, but here is the code for the first ("Units") dropdown:
'Populate the Units dropdown
Dim unitsDT As DataTable
sql = "Select distinct unit from masterunits where abs(active) = 1"
retDS = sqlDAL.runSQLDataSet(sql)
unitsDT = retDS.Tables(0)
DropDownListUnits.DataSource = unitsDT
DropDownListUnits.DataTextField = "unit"
DropDownListUnits.DataValueField = "unit"
DropDownListUnits.DataBind()
What am I missing or doing wrong?
I had to change this:
Dim selectedMember As String = DropDownListMembers.DataValueField
...to this:
Dim selectedMember As String = DropDownListMembers.SelectedItem.Value
I have two data on which I have applied the linq to select some lines :
csql = "select * from V_Vente where code_projet=" & ComProjet.GetColumnValue("code_projet") & " "
Dim tabVnt as Datatable = utilitaire.getDatatable(csql)
Dim query1 = tabVnt.AsEnumerable().Where(Function(r) DirectCast(r("date"), Date) >= dtDu And DirectCast(r("date"), Date) <= dtAu)
Dim tabAnnule As DataTable = utilitaire.getDatatable("select * from V_Reserv_Annule")
Dim query2 = From cust In tabAnnule.AsEnumerable() Where (cust.type = "définitif" Or cust.type = "Transfert") And cust.date_annule <= dtAu
now what i want is to select rows from "query1" where "Num_R" not exist in "query2".
The column "Num_r" exist in both datatable "tabVnt" and "tabAnnule"
I've tried this code but he doesn't work,please help me to find the error :
dim rows = from t1 in query1 .AsEnumerable() join t2 in query2.AsEnumerable() on t1.Field(Of String)("Num_r") equals t2.Field(Of String)("Num_r") Into tg
From tcheck In tg.DefaultIfEmpty()
Where tcheck = null
Select t1()
If I have understood your code right, you can check if second table's Num_rs does not contain the table one Num_r:
Dim rows = t1.Where(x=> !t2.Select(y=> y.Num_r).Contains(x.Num_r));
I have find the solution for my issus ,and i'd like to share it here with you :
Dim csql = "select * from V_Vente where code_projet=" & ComProjet.GetColumnValue("code_projet") & " "
Dim tabVnt As DataTable = utilitaire.getDatatable(csql)
Dim query1 = tabVnt.AsEnumerable().Where(Function(r) DirectCast(r("date"), Date) >= dt1 And DirectCast(r("date"), Date) <= dt2).ToList
Dim tabAnnule As DataTable = utilitaire.getDatatable("select * from V_Reserv_Annule")
bannedCCList = From c In tabAnnule.AsEnumerable() _
Where (c!type.Equals("définitif") = True Or c!type.Equals("Transfert") = True) And c!date_annule <= dt2
Select c.Field(Of String)("num_recu")
Dim exceptData = (From c In query1.AsEnumerable() _
Where Not bannedCCList.Contains(c.Field(Of String)("num_recu")) _
).ToList
I am trying to convert this query:
select sales.TTL_Sales_Net, sales.TTL_Sales_Target, units.TTL_Units_Net
from epos_Anal_Branch_Sales_Day sales
join epos_PULL_PM_SKU_STATUS till on sales.BRANCH_ID = till.BRANCH_ID
join epos_Anal_Branch_Units_Day units on sales.BRANCH_ID = units.BRANCH_ID
where till.BRANCH_ID = 45 and sales.DATEKEY = 20140725 and units.DATEKEY = 20140725
from SQL into an Entity Framework query in VB.net. I am sending in the BRANCH_ID in my function and producing the datekey like so:
Dim MyDate As String = Date.Now.ToString("yyyyMMdd")
This is what I have but it just returns no results and I am at a complete loss as to why! This is my query thus far, if anyone can spot what I have done wrong then I would be grateful for a push in the right direction
Public Class clsStoreSales
Public Property DailyAmount As String
Public Property DailyUnits As String
Public Property SalesTarget As String
Public Property ErrorMessages As String
Public Shared Function GetStoreSales(ByVal BranchID As String) As List(Of clsStoreSales)
Dim live As New RMISEntitiesLive
Dim MyDate As String = Date.Now.ToString("yyyyMMdd")
Dim l As New List(Of clsStoreSales)
Try
Dim r = From till In live.epos_PULL_PM_SKU_STATUS
Join sales In live.epos_Anal_Branch_Sales_Day On till.BRANCH_ID Equals sales.BRANCH_ID
Join units In live.epos_Anal_Branch_Units_Day On till.BRANCH_ID Equals units.DATEKEY
Where till.BRANCH_ID = CDbl(BranchID) AndAlso sales.DATEKEY = CDbl(MyDate) AndAlso units.DATEKEY = CDbl(MyDate)
Select New With {.SalesAmount = sales.TTL_Sales_Net, .SalesTarget = sales.TTL_Sales_Target, .SaleUnits = units.TTL_Units_Net}
For Each t In r
Dim m As New clsStoreSales
m.DailyAmount = CStr(t.SalesAmount)
m.DailyUnits = CStr(t.SaleUnits)
m.SalesTarget = CStr(t.SalesTarget)
l.Add(m)
Next
Return l
Catch ex As Exception
Dim e As New clsStoreSales
e.ErrorMessages = ex.ToString
l.Add(e)
Return l
End Try
End Function
End Class
This is what sqlServer Profiler is showing as the query being run:
exec sp_executesql N'SELECT
[Extent1].[BRANCH_ID] AS [BRANCH_ID],
[Extent2].[TTL_Sales_Net] AS [TTL_Sales_Net],
[Extent2].[TTL_Sales_Target] AS [TTL_Sales_Target],
[Extent3].[TTL_Units_Net] AS [TTL_Units_Net]
FROM [dbo].[epos_PULL_PM_SKU_STATUS] AS [Extent1]
INNER JOIN [dbo].[epos_Anal_Branch_Sales_Day] AS [Extent2] ON [Extent1].[BRANCH_ID] = [Extent2].[BRANCH_ID]
INNER JOIN [dbo].[epos_Anal_Branch_Units_Day] AS [Extent3] ON [Extent1].[BRANCH_ID] = [Extent3].[DATEKEY]
WHERE ( CAST( [Extent1].[BRANCH_ID] AS float) = #p__linq__0) AND ( CAST( [Extent2].[DATEKEY] AS float) = #p__linq__1) AND ( CAST( [Extent3].[DATEKEY] AS float) = #p__linq__2)',N'#p__linq__0 float,#p__linq__1 float,#p__linq__2 float',#p__linq__0=45,#p__linq__1=20140725,#p__linq__2=20140725
This
Join units In live.epos_Anal_Branch_Units_Day On till.BRANCH_ID Equals units.DATEKEY
Should be this!
Join units In live.epos_Anal_Branch_Units_Day On till.BRANCH_ID Equals units.BRANCH_ID
What is the proper syntax for .ToDictionary to return the following as a Dictionary(Of String, String) where ShortDesc is the key and CurrentFrontSymbol is the value
Dim dicQuery As Dictionary(Of String, String) = (From d In toolkitEntities.currentfrontcommoditysymbols
Select d.ShortDesc, d.CurrentFrontSymbol)
Update
And can the following functions query and following For Each loop become one LINQ query?
Public Shared Function GetRangeProjectionPerformance(Optional daysToRetrieve As Integer = 100) As Dictionary(Of Integer, List(Of ProjectionPerformance))
Dim todaysDate As Date = DateTime.Now.Date
Dim lookbackDate As Date = todaysDate.AddDays(daysToRetrieve * -1)
Dim temp As New Dictionary(Of Integer, List(Of ProjectionPerformance))
Using ctx As New ProjectionsEntities()
Dim query = (From d In ctx.projections
Where d.SymbolId <= 42 AndAlso d.Date >= lookbackDate
Join t In ctx.symbols On d.SymbolId Equals t.Id
Let actualRange = d.HighProjection - d.LowProjection
Select New With {
d.Date,
d.SymbolId,
t.Name,
actualRange}).GroupBy(Function(o) o.SymbolId).ToDictionary(Function(p) p.Key)
For Each itm In query
Dim rpp As New ProjectionPerformance
Dim rppList As New List(Of ProjectionPerformance)
If itm.Value.Count > 0 Then
For x As Integer = 0 To itm.Value.Count - 1
Dim bb As Integer = Convert.ToInt32(itm.Value(x).SymbolId)
With rpp
.SymbolId = bb
.ProjectionDate = itm.Value(x).Date.ToString()
.Name = itm.Value(x).Name
.ProjectedRange = itm.Value(x).actualRange
End With
rppList.Add(rpp)
Next
End If
temp.Add(itm.Key, rppList)
Next
End Using
Return temp
End Function
As you do not have a special projection in the select, you can just call ToDictionary on the collection. The first lambda expression retrieves the key, the second one the value.
Dim dicQuery = toolkitEntities.currentfrontcommoditysymbols.ToDictionary( _
Function(x) x.ShortDesc, _
Function(y) y.CurrentFrontSymbol)
As for your update: the following query should get you the desired result:
Dim query = (From d In ctx.projections
Where d.SymbolId <= 42 AndAlso d.Date >= lookbackDate
Join t In ctx.symbols On d.SymbolId Equals t.Id
Let actualRange = d.HighProjection - d.LowProjection
Select New With {
d.Date,
d.SymbolId,
t.Name,
actualRange}).GroupBy(Function(o) o.SymbolId)
.ToDictionary(Function(p) p.Key,
Function(x) x.Select(Function(y) New ProjectionPerformance() With {
.SymbolId = Convert.ToInt32(y.SymbolId),
.ProjectionDate = y.Date.ToString(),
.Name = y.Name,
.ProjectedRange = y.actualRange
}).ToList())