Filtering DBNull With LINQ - vb.net

Why does the following query raise the error below for a row with a NULL value for barrel when I explicitly filter out those rows in the Where clause?
Dim query = From row As dbDataSet.conformalRow In dbDataSet.Tables("conformal") _
Where Not IsDBNull(row.Cal) AndAlso tiCal_drop.Text = row.Cal _
AndAlso Not IsDBNull(row.Tran) AndAlso tiTrans_drop.Text = row.Tran _
AndAlso Not IsDBNull(row.barrel) _
Select row.barrel
If query.Count() > 0 Then tiBarrel_txt.Text = query(0)
Run-time exception thrown : System.Data.StrongTypingException - The value for column 'barrel' in table 'conformal' is DBNull.
How should my query / condition be rewritten to work as I intended?

By default, in strongly typed datasets, properties throw that exception if the field is null. You need to use the generated Is[Field]Null method :
Dim query = From row As dbDataSet.conformalRow In dbDataSet.Tables("conformal") _
Where Not row.IsCalNull() AndAlso tiCal_drop.Text = row.Cal _
AndAlso Not row.IsTranNull() AndAlso tiTrans_drop.Text = row.Tran _
AndAlso Not row.IsbarrelNull() _
Select row.barrel
If query.Count() > 0 Then tiBarrel_txt.Text = query(0)
Or the DataRow.IsNull method :
Dim query = From row As dbDataSet.conformalRow In dbDataSet.Tables("conformal") _
Where Not row.IsNull("Cal") AndAlso tiCal_drop.Text = row.Cal _
AndAlso Not row.IsNull("Tran") AndAlso tiTrans_drop.Text = row.Tran _
AndAlso Not row.IsNull("barrel") _
Select row.barrel
If query.Count() > 0 Then tiBarrel_txt.Text = query(0)

This worked for me.
Dim query = From row As dbDataSet.conformalRow
In dbDataSet.Tables("conformal") _
Where row.Cal.Length > 0 AndAlso tiCal_drop.Text = row.Cal _
AndAlso row.Tran.Length > 0 AndAlso tiTrans_drop.Text = row.Tran _
AndAlso row.barrel.Length > 0 _
Select row.barrel

Related

Visual Basic Or, OrElse still returning false

I am new to VB.net and i have little problem with this statement, i want to throw msgBox just if in txtBox txtTitul is not "Bc." or "" or "Ing." ...
and this is throwing msgBox everytime
If Not txtTitul.Text.Equals("Bc.") _
OrElse Not txtTitul.Text.Equals("") _
OrElse Not txtTitul.Text.Equals("Bc.") _
OrElse Not txtTitul.Text.Equals("Mgr.") _
OrElse Not txtTitul.Text.Equals("Ing.") _
OrElse Not txtTitul.Text.Equals("Mgr. art.") _
OrElse Not txtTitul.Text.Equals("Ing. arch.") _
OrElse Not txtTitul.Text.Equals("MUDr.") _
OrElse Not txtTitul.Text.Equals("MVDr.") _
OrElse Not txtTitul.Text.Equals("RNDr.") _
OrElse Not txtTitul.Text.Equals("PharmDr.") _
OrElse Not txtTitul.Text.Equals("PhDr.") _
OrElse Not txtTitul.Text.Equals("JUDr.") _
OrElse Not txtTitul.Text.Equals("PaedDr.") _
OrElse Not txtTitul.Text.Equals("ThDr.") Then
MsgBox("Neplatny titul!")
Exit Sub
End If
You don't want to use OrElse but AndAlso, because only if it's not one of those it's an invalid title (so not 1st and not 2nd and not 3rd and so on....).
But can i show you a much simpler and more maintainable approach?
Dim allowedTitles = {"Bc.","Ing.","Ing. arch.","MUDr.","MVDr.","RNDr.","PhDr.","PaedDr.","ThDr."}
If Not allowedTitles.Contains(txtTitul.Text) Then
MsgBox("Invalid title!")
End If
If you also want to accept lower-case, so ignore the case, you can use:
If Not allowedTitles.Contains(txtTitul.Text, StringComparer.InvariantCultureIgnoreCase) Then
MsgBox("Invalid title!")
End If
Consider your input is "Bc."
Not txtTitul.Text.Equals("Bc.") <- false
Not txtTitul.Text.Equals("") <- true
false OrElse true = true
Consider your input is "abc"
Not txtTitul.Text.Equals("Bc.") <- true
Not txtTitul.Text.Equals("") <- true
true OrElse true = true
For solution, you may consider Tim's answer.

Linq Select with Where based on Dropdown values

I have a search page that has a series of 3 dropdowns that the user can use to limit the search results. Each of the dropdowns has an initial value of ALL. If any have a value other than ALL I need to include that as a WHERE statement.
This is where I become stuck. My Linq Select is...
Dim myComponents = From searchComponents In dc.Components _
Where searchComponents.Type = ddl_Type.SelectedValue _
AndAlso searchComponents.Size = ddl_Size.SelectedValue _
AndAlso searchComponents.WR = ddl_WR.SelectedValue _
Select searchCompnents)
At the moment my search will include all ddl selectedValues. I need to remove any that have a value of ALL. I hope I've explained correctly. Example if ddl_Size.SelectedValue = "ALL" then my statement would be...
Dim myComponents = From searchComponents In dc.Components _
Where searchComponents.Type = ddl_Type.SelectedValue _
AndAlso searchComponents.WR = ddl_WR.SelectedValue _
Select searchCompnents)
How can I achieve this in code. Thanks
Dim myComponents = From searchComponents In dc.Components _
Where (ddl_Type.SelectedValue = "ALL" OrElse searchComponents.Type = ddl_Type.SelectedValue) _
AndAlso (ddl_Size.SelectedValue = "ALL" OrElse searchComponents.Size = ddl_Size.SelectedValue) _
AndAlso (ddl_WR.SelectedValue = "ALL" OrElse searchComponents.WR = ddl_WR.SelectedValue) _
Select searchCompnents)

print selected row from datagridview Error

i am using this code to print selected row from datagridview & I receive This Error (Cannot perform '=' operation on System.Int32 and System.String.)
Me.salesTableAdapter.Fill(Me.ordersDataSet.sales)
Me.ordersDataSet.sales.DefaultView.RowFilter = "id='" &
Form1.SalesDataGridView.Item(1, Form1.SalesDataGridView.CurrentRow.Index).Value &
"'"
salesBindingSource.DataSource = Me.ordersDataSet.sales.DefaultView
Me.ReportViewer1.RefreshReport()
Drop the ''.
Me.ordersDataSet.sales.DefaultView.RowFilter = String.Format("id={0}", Form1.SalesDataGridView.Item(1, Form1.SalesDataGridView.CurrentRow.Index).Value)
If the column/field is nullable you could do:
Dim value As Object = Me.SalesDataGridView.Item(1, Me.SalesDataGridView.CurrentRow.Index).Value
If ((value Is Nothing) OrElse ((TypeOf value Is DBNull) OrElse ((TypeOf value Is System.Data.SqlTypes.INullable) AndAlso DirectCast(value, System.Data.SqlTypes.INullable).IsNull))) Then
Me.ordersDataSet.sales.DefaultView.RowFilter = "[id] IS NULL"
Else
Dim id As Integer = System.Convert.ToInt32(value)
Me.ordersDataSet.sales.DefaultView.RowFilter = String.Format("[id]={0}", id)
End If

LINQ VB.NET Check Date between Effective and End Date (End Date can be null)

I have a LINQ query VB.NET that I have to check if a Date is between the timespan --- Here is the twist the Effective Date is required, but the End Date can be nullable
I can have the same record but the dates cannot overlap
.Where(Function(x) x.srvc_def_desc = txtSrvDefDesc.Text.Trim()) _
.Where(Function(x) txtsrvEffDt.SelectedDate >= x.eff_dt And (txtsrvEffDt.SelectedDate <= x.end_dt)).Count()
The problem I am having is how to I check for a nullable date to count as a date being between the Effective and a End Date that does not expire?
.Where(Function(x) _
x.srvc_def_desc = txtSrvDefDesc.Text.Trim() _
AndAlso txtsrvEffDt.SelectedDate >= x.eff_dt _
AndAlso (Not txtSrvEffDt.HasValue() OrElse txtsrvEffDt.SelectedDate <= x.end_dt)).Count()
which can be simplified to (if the Count is all you're interested in):
.Count(Function(x) _
x.srvc_def_desc = txtSrvDefDesc.Text.Trim() _
AndAlso txtSrvEffDt.SelectedDate >= x.eff_dt _
AndAlso (Not txtSrvEffDt.HasValue() OrElse txtsrvEffDt.SelectedDate <= x.end_dt))

Linq to entities. GetPropety(name).GetValue not recognised by linq

I have a listbox on my xaml form that I bound to a List(Of MyType) property. I populated this list like so:
Dim fields As List(Of CheckableFields) = New List(Of CheckableFields)
Using context As ITIPEntities = New ITIPEntities()
Try
Dim propertyInfoList As List(Of PropertyInfo) = GetType(PC).GetProperties().ToList()
For Each pI In propertyInfoList
If (pI.PropertyType <> GetType(EntityState) _
And pI.PropertyType <> GetType(EntityKey) _
And pI.PropertyType <> GetType(EntityCollection(Of DiskDrive)) _
And pI.PropertyType <> GetType(EntityCollection(Of Memory)) _
And pI.PropertyType <> GetType(EntityCollection(Of Monitor)) _
And pI.PropertyType <> GetType(EntityCollection(Of Network)) _
And pI.PropertyType <> GetType(EntityCollection(Of Processor))) Then
fields.Add(New CheckableFields(pI.Name))
End If
Next
Catch ex As Exception
End Try
End Using
Now I'm at the point where the user selects the fields they want included in a report and I need to iterate over the required fields. This is my linq query:
For Each checkedField In _requiredFields
If checkedField.IsChecked Then
If checkedField.FieldData IsNot Nothing AndAlso checkedField.FieldData.Trim IsNot String.Empty Then
Dim fieldData As String = checkedField.FieldData
Dim name As String = checkedField.Name
lquery = From comp In lquery Where CType(comp.GetType.GetProperty(name).GetValue(comp, Nothing), String).ToUpper.Contains(fieldData.ToUpper) Select comp
End If
End If
Next
Which throws the exception that linq doesn't recognize the GetValue method.
How can I get the property values dynamically?
Edit:
I couldn't find a way to do this with Linq to Entities, but I did find a way without Linq that works for me:
For Each field In _requiredFields
If field.IsChecked Then
reportGenerator.AllFields.Add(field.Name)
If field.FieldData IsNot Nothing Then
For i As Integer = pcs.Count - 1 To 0 Step -1
Dim compPropertyValue As String = CType(pcs(i).GetType().GetProperty(field.Name).GetValue(pcs(i), Nothing), String).ToUpper()
If Not compPropertyValue.Contains(field.FieldData.ToUpper()) Then
pcs.RemoveAt(i)
End If
Next i
End If
End If
Next
This construct is not supported in LINQ-to-Entities. It is a designed limitation.
Try using Entity SQL instead as shown in the following example:
"SELECT VALUE comp From COMPs AS comp WHERE comp." & name & ".ToUpper().Contains(" & fieldData & ".ToUpper()"