DataTable DefaultView Rowfilter doesnt work - c#

I have a gridview that uses a DataTable as datasource. When I'm trying to hardcode the RowFilter string it works well, but when I use GetFilterExpression() it doesn't work. Why?
I've checked the string returned by GetFilterExpression and match it with an if check and I saw it exactly matches my hardcoded string.
var list = (List<ResaveBase>)listGridRows;
var dt = ToDataTable(list);
dt.DefaultView.RowFilter = GetFilterExpression(); //When hardcoding this, it works
gvwResavePositions.DataSource = dt;
gvwResavePositions.DataBind();
private string GetFilterExpression()
{
string filterExpression = String.Empty;
filterExpression = string.IsNullOrEmpty(txtPaperId.Text)
? string.Empty
: string.Format("strPaperId IN ({0})", txtPaperId.Text);
return filterExpression;
}

This should fix it:
gvwResavePositions.DataSource = dt.DefaultView;

as per my knowledge expression must comes in quotation marks. it may possible your function results comes without quotes.
you can write logic in function and return value only and call function like -
String.Format("strPaperId IN ({0})", GetFilterExpression());

Related

c# wildcards not matching datatable column values

I am having an issue trying to match data table column names with a string containing a wildcard.
I have a data table with various column names which includes a set named like follows: "PsA", "PsB", "PsC", ect. I want to iterate through all the columns containing Ps in the title and use those titles to extract the data.
I currently have the following code which fails to return any matches. I have substituted a straight value in the if statement ("PsA") as a test, which works fine; however, when I use the wildcard, I get no matches. I have also tried Regex with no luck.
private void dfaSection_SelectedIndexChanged(object sender, EventArgs e)
{
string psText = null;
string colID = "Ps*";
offBox.Text = ""; //Clear textbox if a reselection occurs
psBox.Text = ""; //Clear textbox if a reselection occurs
info.offTitle = dfaSection.Text; //Set textbox from variable
dt = opr.findOffByTitle(info); //Get datatable from SQL database
if(dt.Rows.Count > 0)
{
offBox.Text = dt.Rows[0][5].ToString(); //Set textbox from datatable
foreach(DataColumn dc in dt.Columns) //Loop through datatable columns
{
if (dc.ColumnName.ToString() == colID) //Check that column title matches test string - Later addition--> && dt.Rows[0][dc].ToString() != null)
{
psText = dt.Rows[0][dc].ToString() + "\n\n"; //Add data from matched column to string variable
}
}
psBox.Text = psText; //Set textbox from variable
}
}
Edit: Issue fixed using .Contains(colID) Column names now being matched, string are now not being loaded to the psText variable, but I'll spend some time with that and get it working. Thanks Skaros Ilias.
I am not so failiar with C, but == for sure is not the right method.
you need to use the contains method. As I said, I am not familiar with it, but the docs have a good example of it.
String s = "This is a string.";
String sub1 = "this";
Console.WriteLine("Does '{0}' contain '{1}'?", s, sub1);
StringComparison comp = StringComparison.Ordinal;
Console.WriteLine(" {0:G}: {1}", comp, s.Contains(sub1, comp));
take a breakpoint a check what is column name and colID at failure moment.How are you going to solve problems, when don't even know values?
Use dc.ColumnName.ToString().StartsWith(). Contains() is good only untill string endswith.
As per this answer before : Regular expression wildcard
And here is sample of code :
private static bool Match(string pattern, string stringToCheck) {
var finalPattern = pattern.Replace("*", ".*?");
Regex regex = new Regex(finalPattern);
return regex.IsMatch(stringToCheck);
}

How can I populate a generic list of string with the results from a single-column DataTable?

I see a lot of complex examples for converting a DataTable with multiple-member rows here but in my case, the query simply returns one column from a table, that is to say 0..N strings/varchars, such as:
bbfinaleofseem#wallacestevens.org
eyenoy#dunbar.com
I thought something like this should work:
DataTable UnitReportPairEmailValsDT = new DataTable();
string qry = string.Format(SQL.UnitReportPairEmailQuery, unit, rptId);
UnitReportPairEmailValsDT = SQL.ExecuteSQLReturnDataTable(
qry,
CommandType.Text,
null
);
List<String> emailAddresses = new List<string>();
foreach (string emailaddr in UnitReportPairEmailValsDT)
{
emailAddresses.Add(emailaddr);
}
...but it won't compile ("foreach statement cannot operate on variables of type 'System.Data.DataTable' because 'System.Data.DataTable' does not contain a public definition for 'GetEnumerator'")
I tried appending ".AsEnumerable" to "in UnitReportPairEmailValsDT" too, but that also provoked the wrath of the compiler.
Error says you cannot loop through DataTable object itself, probably what you need is looping through DataRows.
Use this.
foreach(DataRow row in UnitReportPairEmailValsDT.Rows)
{
emailAddresses.Add(row["emailaddr"].ToString()); // assuming you have emailaddr column.
}
Other option, use Linq
emailAddresses = UnitReportPairEmailValsDT
.AsEnumerable()
.Select(row=> row.Field<string>("emailaddr"))
.ToList();
try something like this:
List<String> emailAddresses = new List<string>();
foreach (DataRow row in UnitReportPairEmailValsDT.Rows)
{
emailAddresses.Add(row.Item(0));
}
Suppose dt is your data table then using Linq:
dt.Rows.Select(x=> x[0]+"").ToList() will give you List. Beware of using Select(x=>xToString()) as it is prone to error if column value is null. x[0]+"" makes sure that in case of null empty string is returned.

TableAdapter Query with optional WHERE paramerter

I am trying to create a TableAdapter query with an optional WHERE parameter.
This is my query:
SELECT Productos.Categoria, Productos.Subcategoria, Productos.Nombre,
Productos.Marca, Productos.Descripcion, Proveedores.Nombre AS Proveedor, Precios.Precio
FROM Precios, Productos, Proveedores
WHERE Precios.Producto_ID = Productos.ID AND Precios.Proveedor_ID =
Proveedores.ID AND Proveedores.Nombre = ?
I would like "Proveedores.Nombre = ?" to be optional or if ? = null or nothing, the query does not filter by Proveedores.Nombre
I have tried this:
(Proveedores.Nombre =#PNombre OR #PNombre = NULL)
But I have got an error:
Generated SELECT statement:
Error in WHERE clause near '#'.
Unable to parse the query text
Thank you very much for you help,
Regards
Andres
EDIT:
I ma in a windows form project. I am using a DataSource - DataSet linked to my access database. So to create FillBy() and GetData() I use a table-adapter which was automatically created when I inserted the DataSource to my WindowsForm.
This is the method created liked to the GetData() I am using:
public virtual DB_ProvProd2DataSet.ProductosDataTable GetDataByTodo(string Nombre) {
this.Adapter.SelectCommand = this.CommandCollection[5];
if ((Nombre == null)) {
throw new global::System.ArgumentNullException("Nombre");
}
else {
this.Adapter.SelectCommand.Parameters[0].Value = ((string)(Nombre));
}
DB_ProvProd2DataSet.ProductosDataTable dataTable = new DB_ProvProd2DataSet.ProductosDataTable();
this.Adapter.Fill(dataTable);
return dataTable;
}
Where this.CommandCollection[5] = the query and this.Adapter.SelectCommand.Parameters[0] is the input related to the '?' of the query.
I hope this helps!
Thanks!!!
Try assing it to a local variable:
string tmp= #PNombre
(Proveedores.Nomber==tmp || tmp == null)

c# CheckedListbox values

When I want to put the values in an array that are selected from a checkedlistbox. And then say:
messagebox.show(values[0]);
It's saying : System.Data.DataRowView
This is my current code:
string[] itemArr = new string[clbTables.CheckedItems.Count];
int counter = 0;
foreach (object item in this.clbTables.CheckedItems)
{
string temp = Convert.ToString(item);
itemArr[counter] = temp;
counter++;
}
MetroMessageBox.Show(this, itemArr[0].ToString());
What am I doing wrong here>?
EDIT ::
clbTables.DataSource = sqlDisplayContent.connectDataTable("SELECT ('Tafelnr: '+ CONVERT(varchar,tafelnr)+' Zitplaatsen: '+ CONVERT(varchar,zitPlaatsen)) AS dispValue,tafelnr FROM tabel");
clbTables.DisplayMember = "dispValue";
clbTables.ValueMember = "tafelnr";
class sqlDisplayContent
{
public static DataTable connectDataTable(string query)
{
SqlCommand comm= sqlCrud.returnSqlCommand(query);
SqlDataAdapter sda = new SqlDataAdapter(comm);
DataTable dt = new DataTable();
sda.Fill(dt);
return dt;
}
}
Thankss
The issue is that:
Convert.ToString(item);
will simply call the ToString() method of the object and store that, which in this case, is giving you the object's type. In this case, the type is System.Data.DataRowView. I suggest that you access the specific field in the row that you want by using:
((DataRowView)item).Row["FieldName"].ToString();
instead. You will want to replace "FieldName" with whatever the name of your column that you are wanting is. Additionally, you can use an int index instead of a string reference. Of course, if you need to access multiple fields, you can do this by simple string concatenation. The issue is that you need to access the specific field that you want. Not the entire row as you are currently on.
I hope this helps!
A couple references: DataRow, DataRowView
I suppose that your values[] array is not right. Please, refer to this example on MSDN.
https://msdn.microsoft.com/en-us/library/system.windows.forms.checkedlistbox.checkeditems(v=vs.110).aspx
string temp = ((CheckBox)item).Text;
You are passing in the object, not the object's text (which is what it seems you want the code to do).

Find value from the dataview using column name

I am trying to find value from dataview using column name. My dataset shows value but my if condition returns false. I am working in asp.net using c#.
I have tried with different code. I am trying to get value like this
dv[0].DataView.Table.Columns[0].ToString().Contains("52")
//RETURN FALSE
OR
dv[0].Equals("52")
// //RETURN FALSE
OR
dv[0].Find("52")
// //RETURN FALSE
Following is my dataset
If "GBA_Nbr_GBAccount" column is a string type, it may contains spaces.
You should trim text before comparing. Try this
dv[0]["GBA_Nbr_GBAccount"].ToString().Trim().Equals("52");
You could use Linq to query the datatable or the dataview. For example, assuming your column is of type string:
var condition = yourDataTable.AsEnumerable()
.Any(r => r.Field<string>("GBA_Nbr_GBAccount") == "52");
var condition = yourDataView.Cast<DataRowView>()
.Any(rv => rv.Row.Field<string>("GBA_Nbr_GBAccount") == "52");
If the column was an integer, just change the Field<string> to Field<int> and compare against an integer, not a string
var condition = yourDataTable.AsEnumerable()
.Any(r => r.Field<int>("GBA_Nbr_GBAccount") == 52);
var condition = yourDataView.Cast<DataRowView>()
.Any(rv => rv.Row.Field<int>("GBA_Nbr_GBAccount") == 52);
Example application using string column:
static void Main(string[] args)
{
DataSet dataset = new DataSet();
dataset.Tables.Add(new DataTable("table1"));
dataset.Tables[0].Columns.Add(new DataColumn("Value", typeof(string)));
dataset.Tables[0].Rows.Add("10");
dataset.Tables[0].Rows.Add("52");
DataTable table = dataset.Tables[0];
DataView view = table.DefaultView;
var condition1 = table.AsEnumerable().Any(r => r.Field<string>("Value") == "52");
var condition2 = view.Cast<DataRowView>().Any(rv => rv.Row.Field<string>("Value") == "52");
Console.WriteLine(String.Format("Result querying datatable: '{0}'. Result using dataview:'{1}'", condition1, condition2));
Console.ReadLine();
}
If you are really using a string for the column, check for white spaces and apply a trim if needed.
One way to check for the existence of a specific column in a dataview would be like the following:
if (dv.Table.Columns["Name"] != null)
{
//Name column exists. Add Logic here
}
Use the DataViewManager object instead
it has a DataSet property associated with it and the dataset has all the normal dataset features. So, you can traverse the dataset.tables[index] object...
Hope it helps
Example: dv.DataViewManager.DataSet.Tables[0].Rows[0][1]
Thanks,
Sam
int rowIndex = dv.Find("52");
if (rowIndex == -1) {
Console.WriteLine("No match found.");
}
else {
Console.WriteLine("{0}, {1}",
dv(rowIndex)("GBA_Nbr_GBAccount").ToString(),
dv(rowIndex)("GBA_Nam_GBAccount").ToString());
}
I think that may be the solution to your problem, or at the very least point you in the right direction.

Categories