list.longcount query using joins (Linq/Lambda) - vb.net

I have two lists of class objects (Shifts and Employees) with which I am trying to create a join. I then need a count of the resulting items that match the search criteria.
Below is the code I am using, but because I can't find a way to pass the result back as a specific 'type' it's defaulting to boolean and warning me that this will cause a problem:
' Count Shifts for selected hour where: started before or on this
"hour" AND ends after or during this "hour" and Department = filter
value
intShift = Me.Shifts.LongCount(From myshift In Me.Shifts Join
myEmp In Me.EmployeesList On myshift.EmployeeName Equals myEmp.Name
Where myshift.Description = "Shift" And myshift.DateStart.Hour <=
myHour.Hour And myshift.DateEnd.Hour >= myHour.Hour _
And myshift.DateStart.Date = myDay.Date And myEmp.Department =
strFilter _ Or myshift.Description = "Overtime" And
myshift.DateStart.Hour <= myHour.Hour And myshift.DateEnd.Hour
>= myHour.Hour _
And myshift.DateStart.Date = myDay.Date And myEmp.Department =
strFilter)
The search without a join to the employee list and without the matching employee search filters works perfectly but just unable to combine the two.
I have searched for both linq/lambda and inner join examples, but I can't seem to find one that combines these with the longcount function.

I've tried to put together a minimal scenario based on your snippet.
If you request Count or LongCount directly from the query then the result appears to be as expected.
Dim Shifts() = {
New With {.DateStart = #1/1/2014#,
.DateEnd = #1/2/2014#,
.Description = "Overtime",
.EmployeeName = "Darren"}
}
Dim EmployeesList() = {
New With {.Name = "Darren",
.Department = "SO"}
}
Dim strFilter = "SO"
Dim myHour = #1/1/2014#
Dim myDay = myHour
Dim query =
From myshift In Shifts Join myEmp In EmployeesList _
On myshift.EmployeeName Equals myEmp.Name _
Where myshift.Description = "Shift" _
And myshift.DateStart.Hour <= myHour.Hour _
And myshift.DateEnd.Hour >= myHour.Hour _
And myshift.DateStart.Date = myDay.Date _
And myEmp.Department = strFilter _
Or myshift.Description = "Overtime" _
And myshift.DateStart.Hour <= myHour.Hour _
And myshift.DateEnd.Hour >= myHour.Hour _
And myshift.DateStart.Date = myDay.Date _
And myEmp.Department = strFilter
Console.WriteLine(query.Count)
Console.WriteLine(query.LongCount)

Related

Linq with multiple where clauses not pulling back data

I am using VB.NET and Linq; I have two separate conditions that have to be satisfied. When I run them individually they work fine however when I combine them into a single statement with multiple where statements then I get 0 records returned.
If I run the first where clause without the 2nd I get 70 records
If I run the 2nd where clause without the first i get 5 records
When I run with both where clauses I get 0 records returned
Here is the code.
submissionDetails = (From r In model.NIBRS_ReportStatusByORI
Where (sCritera.ORI.Contains(r.OriginatingORI) _
And Not r.ReportType = "ZERO REPORT" _
And r.OccurrenceDate >= sCritera.BeginDate _
And r.OccurrenceDate <= sCritera.EndDate _
And (r.ActionCode <> "D"))
Where (sCritera.ORI.Contains(r.OriginatingORI) _
And r.ReportType.Equals("ZERO REPORT") _
And r.YearMonthDate >= sCritera.BeginDate _
And r.YearMonthDate <= sCritera.EndDate _
And (r.ActionCode <> "D"))
Select New ReportStatusDetails() With {
.ChangeDate = r.Insertdate,
.IncidentId = r.IncidentID,
.IncidentIdentifier = r.IncidentIdentifier,
.OriginatingORI = r.OriginatingORI,
.ReportType = r.ReportType,
.StatusID = r.StatusID,
.SubmittedBy = r.Username,
.ReportDate = r.YearMonthDate,
.ReportDateString = r.YearMonth,
.OccurrenceDate = r.OccurrenceDate
}).ToList()
Have you tried this:
submissionDetails = (From r In model.NIBRS_ReportStatusByORI
Where (sCritera.ORI.Contains(r.OriginatingORI) _
And Not r.ReportType = "ZERO REPORT" _
And r.OccurrenceDate >= sCritera.BeginDate _
And r.OccurrenceDate <= sCritera.EndDate _
And (r.ActionCode <> "D"))
Select New ReportStatusDetails() With {
.ChangeDate = r.Insertdate,
.IncidentId = r.IncidentID,
.IncidentIdentifier = r.IncidentIdentifier,
.OriginatingORI = r.OriginatingORI,
.ReportType = r.ReportType,
.StatusID = r.StatusID,
.SubmittedBy = r.Username,
.ReportDate = r.YearMonthDate,
.ReportDateString = r.YearMonth,
.OccurrenceDate = r.OccurrenceDate
}).Union(From r In model.NIBRS_ReportStatusByORI
Where (sCritera.ORI.Contains(r.OriginatingORI) _
And r.ReportType.Equals("ZERO REPORT") _
And r.YearMonthDate >= sCritera.BeginDate _
And r.YearMonthDate <= sCritera.EndDate _
And (r.ActionCode <> "D"))
Select New ReportStatusDetails() With {
.ChangeDate = r.Insertdate,
.IncidentId = r.IncidentID,
.IncidentIdentifier = r.IncidentIdentifier,
.OriginatingORI = r.OriginatingORI,
.ReportType = r.ReportType,
.StatusID = r.StatusID,
.SubmittedBy = r.Username,
.ReportDate = r.YearMonthDate,
.ReportDateString = r.YearMonth,
.OccurrenceDate = r.OccurrenceDate
}).ToList()

Using Linq for select row from DataTableA where id not in DataTableB

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.

VB.Net Linq with datatables - select from one table what does not exist in the other

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

How to merge cells and remove blank spaces in my DataGrid using proper loop

My title is still broad so i'll explain here further.
This is my current output using my code:
.
But I want to make it look like this..
As you can see on the pictures, i want to remove the blank spaces. Because if I selected MORE data, let's say I selected 7 more days, it will go DIAGONALLY not horizontally.
I think I have a problem regarding my loops. Hope you can help me trace because I've been stuck here for a week debugging. (nevermind my long query, i just want to post all my code. I've also added comments for easier debugging.)
Here's my code:
Private Sub LoadDateAndUser()
Dim SqlStr As String = ""
Dim sqlConn As New SqlConnection(DataSource.ConnectionString)
Dim sqlComm As New SqlCommand(SqlStr, sqlConn)
Dim sqlAdapter As New SqlDataAdapter(sqlComm)
Dim o_Dataset As New DataSet()
SqlStr = " SELECT convert(varchar(10), A.TransDate, 101) as TransDate,ADMMED.TransNum, ADMMED.AdministeredDate, D.Dosage [Dosage], ISNULL(C.GenericName, ' ') + ' (' + IsNull(B.ItemName,'') + ' ' + IsNull(B.ItemDesc,'') + ')' [Medication], ADMMED.UserID" & _
" FROM INVENTORY..tbInvStockCard as A" & _
" LEFT OUTER JOIN INVENTORY..tbInvMaster as B On A.ItemID = B.ItemID " & _
" LEFT OUTER JOIN Inventory.dbo.tbForGeneric as C On B.GenericID = C.GenericID" & _
" LEFT OUTER JOIN Station..tbNurse_AdministeredMedicines ADMMED on a.idnum= ADMMED.idnum " & _
" LEFT OUTER JOIN build_file.dbo.tbCoDosage as D on A.DosageID = D.DosageID" & _
" LEFT OUTER JOIN Station.dbo.tbNurseCommunicationFile as E on A.IdNum = E.IDnum and E.ReferenceNum = A.RefNum" & _
" WHERE A.IdNum = '" & Session.Item("IDNum") & "' and ( A.RevenueID = 'PH' or A.RevenueID = 'PC' ) " & _
" AND A.LocationID = '20' and Not IsNull(ADMMED.AdministeredDate, '') = ''" & _
" AND A.RefNum = ADMMED.ReferenceNum and ADMMED.ItemID = A.itemid" & _
" AND (B.ItemClassificationID = '1' or B.ItemClassificationID = '10' or B.ItemClassificationID = '11' or B.ItemClassificationID = '16' or B.ItemClassificationID = '2' or B.ItemClassificationID = '9')" & _
" order by TransDate desc,ADMMED.AdministeredDate desc"
sqlComm.CommandText = SqlStr
sqlAdapter.Fill(o_Dataset, "Table")
Dim o_Row As DataRow
Dim o_AdmDates As New Collection()
Dim s_FormattedLastAdmDate As String = ""
Dim s_FormattedAdmDate As String = ""
Dim o_DerivedTable As New DataTable()
With o_DerivedTable
.Columns.Add("TransDate")
.Columns.Add("Medication")
.Columns.Add("Dosage")
.Columns.Add("TransNum")
End With
'Select all unformatted administered dates from the query
Dim o_UnformattedAdmDates As DataRow() = o_Dataset.Tables(0).Select("", "AdministeredDate Desc")
'Extract distinct administered dates and change its format
For Each o_Row In o_UnformattedAdmDates
s_FormattedAdmDate = Format(CDate(o_Row.Item("AdministeredDate")), KC_Date_Format) 'eg. Jan 01 15
If s_FormattedLastAdmDate <> s_FormattedAdmDate Then
s_FormattedLastAdmDate = s_FormattedAdmDate
o_AdmDates.Add(s_FormattedLastAdmDate) 'add all formatted dates in o_AdmDates
End If
Next
'Add formatted administred dates to derived table
Dim o_Item As String
For Each o_Item In o_AdmDates
o_DerivedTable.Columns.Add(o_Item)
Next
'Loop through the administred date
Dim o_NewRow As DataRow
Dim o_NextRow As DataRow
Dim i_Ctr As Integer
Dim x_isNewRow As Boolean = True
Dim i_MaxRec As Integer
i_MaxRec = o_Dataset.Tables(0).Rows.Count - 1
For i_Ctr = 0 To i_MaxRec
o_Row = o_Dataset.Tables(0).Rows(i_Ctr)
If i_Ctr <> i_MaxRec Then
o_NextRow = o_Dataset.Tables(0).Rows(i_Ctr + 1)
End If
If x_isNewRow Then
o_NewRow = o_DerivedTable.NewRow()
End If
o_NewRow("TransDate") = o_Row("TransDate")
o_NewRow("Medication") = o_Row("Medication")
o_NewRow("Dosage") = o_Row("Dosage")
o_NewRow("TransNum") = o_Row("TransNum")
'Fill approriate result date column based on query
For Each o_Item In o_AdmDates
s_FormattedAdmDate = Format(CDate(o_Row.Item("AdministeredDate")), KC_Date_Format)
Dim AdmTim As DateTime = DateTime.Parse(o_Row("AdministeredDate"))
If s_FormattedAdmDate = o_Item Then
o_NewRow(s_FormattedAdmDate) = AdmTim.ToString("hh:mm tt") + " - " + o_Row("UserID")
End If
Next
If i_Ctr < i_MaxRec _
And Not o_NextRow Is Nothing _
And o_Row("TransDate") = o_NextRow("TransDate") _
And o_Row("Medication") = o_NextRow("Medication") _
And o_Row("Dosage") = o_NextRow("Dosage") _
And o_Row("AdministeredDate") = o_NextRow("AdministeredDate") Then
x_isNewRow = False
Else
o_DerivedTable.Rows.Add(o_NewRow)
x_isNewRow = True
End If
Next
'Bind derived table
dgSheet.DataSource = o_DerivedTable
dgSheet.DataBind()
If o_Dataset.Tables(0).Rows.Count > 0 Then
GroupGridView(dgSheet.Items, 0, 3)
Else
End If
End Sub
I think you must review your programming logic:
After that huge ugly SqlStr : you will have a DataSet, with a Table with all rows mixed !?
Let's try a pseudo-code:
I think is better to create in that DataSet, 2 Tables:<br>
**first** table with: id, DateOrder, Medication, Dosage <br>
and **second** table with: idDate, FirstTable.id, AdministeredDate
after that you know how many ADMMED.AdministeredDate.Count are, because you must know how manny columns you need to add
create a 3-rd table from iteration of first table, nested with second by ID.
Set as Datasource for DataGridView the Third DataTable.
So you have 2 datasets, and generate this one .. one to many ..
.. I have no time now, if you don't get the ideea .. forget it !

PredicateBuilder + Join + VB.NET

I have a db that contains 3 tables
Products Table Suppliers Table Categories Table
Id Id Id
ProductName SupplierName CategoryName
Quantity . .
SupplierId . .
CategoryId
.
.
I am using PredicateBuilder to select Product accoring to the selected product field (Quantity,Productname...)
How Can I use PredicateBuilder or any other method to Select the Product according to Its Suppliername or Categoryname
Please I am using VB.NET I saw many C# examples but I can not understand it nor translate it
I am thinking of using join in predicateBuilder but I do not how !!!!
To be more clear What I want is to combine multiple field in one search ,Like for example:
Give me a Product where It's Name contains "s" and Quantity <10 and SupplierName is Kimo
Give me a product where i's name contains "g" only
give me the products for categoryName "Machines"
.
.
And this search predicate is changable because Each Products table has many fields ,So the search is dynamic according to selected fields
Waiting for your kind help.
I think Arion answer was correct but It needs some revision
AnyWay I came up with this solution ,It is not the most effecient one but It solved my problem.
Dim SupplierAlso As String = ""
Dim CategoryAlso As String = ""
Dim pred = PredicateBuilder.True(Of Products)()
Select Case Entry
Case "Number"
Dim Inum = Entry
pred = pred.And(Function(m As products) m.ID.Equals(CInt(Inum)))
Case "ProductName"
Dim IName = Entry
pred = pred.And(Function(m As Products) m.ProductName.IndexOf(IName, StringComparison.OrdinalIgnoreCase) >= 0)
.
.
.
Case "Supplier"
SupplierAlso = Entry
Case "Category"
CategoryAlso = Ent
Next
Dim f As ProductsDataTable = Products.Product
Dim tmp As IEnumerable(Of Products) = New ProductsDataTable().AsEnumerable()
tmp = f.AsEnumerable.Where(pred.Compile)
Dim qry
If CategoryAlso = "" And SupplierAlso = "" Then
q = (From prods In tmp
Join Cats In Categories
On prods.CategoryId Equals Cats.ID
Join Supps In Suppliers
On Supps.ID Equals prods.SupplierId
Select Supps.SupplierName, Cats.CategoryName, prods.ID _
, prods.ProductName, prods.UnitPrice, prods.CategoryId _
, prods.SupplierId, prods.Location, _
prods.Description, prods.SellPrice, prods.CountInStock _
, prods.ProductionDate, prods.ExpiryDate, _
prods.ProductType, prods.ProductSeason).ToList
ElseIf CategoryAlso <> "" And SupplierAlso <> "" Then
q = (From prods In tmp
Join Cats In Categories
On prods.CategoryId Equals Cats.ID
Join Supps In Suppliers
On Supps.ID Equals prods.SupplierId
Where Cats.CategoryName.IndexOf((CategoryAlso)
, StringComparison.OrdinalIgnoreCase) >= 0 And _ Supps.SupplierName.IndexOf((SupplierAlso), _
StringComparison.OrdinalIgnoreCase) >= 0
Select Supps.SupplierName, Cats.CategoryName, prods.ID, _
prods.ProductName, prods.UnitPrice, prods.CategoryId, _
prods.SupplierId, prods.Location, _
prods.Description, prods.SellPrice, prods.CountInStock, _
prods.ProductionDate, prods.ExpiryDate, _
prods.ProductType, prods.ProductSeason).ToList
ElseIf SupplierAlso <> "" And CategoryAlso = "" Then
q = (From prods In tmp
Join Cats In Categories
On Cats.ID Equals prods.CategoryId
Join Supps In Suppliers
On prods.SupplierId Equals Supps.ID Where _
Supps.SupplierName.IndexOf((SupplierAlso), _
StringComparison.OrdinalIgnoreCase) >= 0
Select Cats.CategoryName, Supps.SupplierName, prods.ID, _
prods.ProductName, prods.UnitPrice, prods.CategoryId, _
prods.SupplierId, prods.Location, _
prods.Description, prods.SellPrice, prods.CountInStock, _
prods.ProductionDate, prods.ExpiryDate, _
prods.ProductType, prods.ProductSeason).ToList
ElseIf CategoryAlso <> "" And SupplierAlso = "" Then
q = (From prods In tmp
Join Cats In Categories
On prods.CategoryId Equals Cats.ID Where Cats.CategoryName.IndexOf _
((CategoryAlso), StringComparison.OrdinalIgnoreCase) >= 0
Join Supps In Suppliers On Supps.ID Equals prods.SupplierId
Select Supps.SupplierName, Cats.CategoryName, prods.ID, _
prods.ProductName, prods.UnitPrice, prods.CategoryId, _
prods.SupplierId, prods.Location, _
prods.Description, prods.SellPrice, prods.CountInStock, _
prods.ProductionDate, prods.ExpiryDate, _
prods.ProductType, prods.ProductSeason).ToList
End If
For Each it In q
With it
DataGridView2.Rows.Add _
({.ID, .ProductName, .UnitPrice, .categoryname, .suppliername, .Location, _
.Description, .SellPrice, .CountInStock, _ .ProductionDate, .ExpiryDate, _
.ProductType, .ProductSeason})
End With
Next
So what do you think ,Is there a better way? Ofcourse yes?Silly question ,But Where?
So i would do something like this then. I have simplify the where statements but I think you will get my point:
dim checkCategoryName as boolean=true
dim checkSupplier as boolean=true
dim checkQuantity as boolean=true
dim query= db.Products.Select (function(p) p)
if checkCategoryName then
query=query _
.Where (function(p) db.Categories.Where (function(c) c.CategoryName="??" ) _
.Select (function(c) c.Id) _
.Contains(p.CategoryId))
end if
if checkSupplier then
query=query _
.Where (function(q) db.Suppliers.Where (function(s) s.SupplierName="??") _
.Select (function(s) s.Id) _
.Contains(q.SupplierId))
end if
if checkQuantity then
query=query.Where (function(q) q.Quantity<10)
end if
dim result=query.ToList()
Where db is the linq data context.