Strongly Typed BindingSource Binding Filter

Building a line BindingSource.Filterlooks like an ugly, manual, forced way to filter data already received.

  • No explicit type checking
  • No explicit column name check
  • No explicit SQL syntax check
  • Manual formatting required ToString()
  • DataSet Design changes do not apply to Filter
  • Managing Filterwith multiple criteria from multiple controls quickly becomes tedious, error prone and cumbersome.

Usage typedTableAdapter.FillBy(typedDataSet.typedTable, @params ...)is a powerful, simple, and easy way to "filter" between the database and DataSet.

Does .NET provide any strongly typed filtering between strongly typed controls DataSetand Form(possibly through BindingSource)?

Initial Bounty: An
initial reward was awarded for proving the concept (using LINQ query like DataSource). However, it does not demonstrate how to actually access strongly typed typedTableRowfiltering.

Additional reward:
All castings by IList, DataView, DataRowView, DataRowand typedTableRowturned out to be quite confusing.

Object                         Generic       Watch List Type
------                         --------      ------------
myBindingSource.List           IList         {System.Data.DataView}
myBindingSource.List[0]        object        {System.Data.DataRowView}

((DataRowView)myBindingSource.List[0]).Row
                               DataRow       typedTableRow

Demonstrate BindingSourcewith using a DataSourcestrongly typed LINQ query (i.e.: with typedTableRowfields available in .Where( ... )).

Notes (for shriop):

  • myBindingSource.
  • myBindingSource.DataSource: typedDataSet
  • myBindingSource.DataMember: typedTable

(applied in FilterBtn_Click()):

myBindingSource.DataSource 
    = typedDataSet.typedTable.Where( x => x.table_id > 3).ToList();

, BindingNavigator . , , , StrongTypingException typedDataSet.typedTableRow.get_FIELDNAME(). , , LINQ - .

+4
3

, , , . DataSet AdventureWorks Product. DataGridView TextBox . DataSet . BindingSource . DataSource BindingSource DataSet . DataMember Product, ProductTableAdapter . DataSource DataGridView BindingSource. Text TextBox Name BindingSource, Name Product. OnLoad Fill , TableAdapter Product DataTable. :

this.bindingSource.DataSource = this.adventureWorks.Product.Where(p => !p.IsProductSubcategoryIDNull()).ToList();

, , , TextBox .

ToList , BindingSource - , , ,

The method or operation is not implemented.
   at System.Linq.Enumerable.Iterator`1.System.Collections.IEnumerator.Reset()
   ...

, , Is * Null().

, , , DataSet , . , , DateTime.

ALOT , DataView , DataTable , , , .

, , datarow datatable, DataTable , .

DataRow[] rows = this.adventureWorks.Product.Where(p => !p.IsProductSubcategoryIDNull()).ToArray();
if (rows.Length > 0)
{
    this.bindingSource.DataSource = rows.CopyToDataTable();
}
else
{
    this.bindingSource.DataSource = rows;
}

, DataTable DataSource, , DataTable, DataRow [], DataTable TableAdapter. , , , .

+4

linq :

this.BindingSource.DataSource = ((IList<T>)this.BindingSource.List).Where( ... );
+5

vb.net , , -:

I created an extension for filtering TypedTablesand populated mine BindingSource.Datasourcefrom the filtered view of the output from the filled one typedTable, keeping the original table and saving the schema in the returned table (returning typedTableinstead of DataTable):

Imports System.Runtime.CompilerServices
Imports System.Windows.Forms

Public Module DB_Extensions

    <Extension()> _
    Public Function LINQ_Filter(Of RowT As DataRow)(ByRef table As TypedTableBase(Of RowT), predicate As System.Func(Of RowT, Boolean)) As TypedTableBase(Of RowT)
        ' Create a clone of table structure(without data) to not loose filtered data on original table and return in a new table instead
        Dim ret As TypedTableBase(Of RowT) = table.Clone()
        ' Using .ImportRow() method garantees to not loose original table schema after return
        For Each r As RowT In table.Where(predicate)
            ret.ImportRow(r)
        Next
        Return ret
    End Function

End Module

and use it just like that (you need to import the module DB_Extensionsto work):

myBindingSource.DataSource = someTypedTable.LINQ_Filter(your_filters)
+1
source

Source: https://habr.com/ru/post/1539198/


All Articles