I am getting a datatable object of a certain type from strongly typed dataset, now I want to find out if one of the column "Title" has certain string in it.
I am trying this, is there any better way ?
FruitDataAccess fda = new FruitDataAccess();
FruitDataTable fdt = cda.GetFriuts(fruitCrateID);
DataTable dt = fdt.CopyToDataTable();
var row = dt.Rows.Cast<DataRow>().Any(r => r.ItemArray.Any(c => c.ToString().Contains("whatever")));
Use LINQ TO DataSet/DataTable like:
var search = dt.AsEnumerable()
.FirstOrDefault(r=> r.Field<string>("Title") == "your string");
if(search != null)
{
//found
}
You can also find rows with your condition like:
DataRow[] foundRows;
foundRows = dt.Select("Title Like '%your string%'"); //similar to Contains
See: How to: Locate a Specific Row in a DataTable
Related
My DataTable has the columns - Id, Name, Address. I need to select the column Address only WHERE ID = 7. How do I do this ? No LINQ please.
I was thinking of this -
DataView view = new DataView(MyDataTable);
DataTable distinctValues = view.ToTable(true, "ColumnA");
Now you can select.
DataRow[] myRows = distinctValues.Select();
//Get the desired answer by iterating myRows.
Is there a simpler way ?
thanks.
Well if you don't want to use LINQ, you can use a simple foreach loop:
DataTable distinctValues = view.ToTable(true, "ColumnA");
var myRows = new List<DataRow>();
foreach(DataRow row in distinctValues.Rows)
{
if(row["Id"].ToString() == "7") myRows.Add(row);
}
I have DataTable containing three columns, Name, Date and DialedNumber. I want to get rows on the basis of DialedNumber column having phone number like 03001234567 ...
I am filing datatable with an method return type is datatable.
{
DataTable dt = filldata();
}
Problem is how to use select statement to get rows having number 03001234567 or some other telephone number ?
Try this Suppose you have a variable **string str** which is having that telephone number which you want to get from that data table then you can use this
{
DataTable dt = filldata();
DataRow[] resut = dt.Select("DialedNumber ='" + str + "'");
}
It will return you those rows having same telephone number in column DialedNumber.
If you want to filter from the start, not getting all table rows every time, you should adjust your SQL statement:
SELECT * FROM Table WHERE DialedNumber = #dialedNumber
and in C# use SqlCommand.Parameters.AddWithValue(...) to add the #dialedNumber parameter to the query.
Try to use Linq to DataTable like this
var results = from myRow in dt.AsEnumerable()
where myRow.Field<String>("DialedNumber") == "03001234567"
select myRow;
You can use Linq to DataSet:
string number = "03001234567";
var rows = dt.AsEnumerable()
.Where(r => r.Field<string>("DialedNumber").Contains(number));
You even can project rows into strongly typed objects:
var people = from r in dt.AsEnumerable()
where r.Field<string>("DialedNumber").Contains(number)
select new {
Name = r.Field<string>("Name"),
Date = r.Field<DateTime>("Date"),
DialedNumber = r.Field<string>("DialedNumber")
};
Note: if you want to check exact match of dialed number, then instead of Contains(number) (which is equivalent of LIKE) use == number.
Try like this
private void GetRowsByFilter()
{
DataTable table = DataSet1.Tables["Table1"];
// Presuming the DataTable has a column named Date.
string expression;
expression = "DialedNumber ='03001234567 '";
DataRow[] foundRows;
// Use the Select method to find all rows matching the filter.
foundRows = table.Select(expression);
// Print column 0 of each returned row.
for(int i = 0; i < foundRows.Length; i ++)
{
Console.WriteLine(foundRows[i][0]);
}
}
DataTable.Select Method
I currently have a DataTable with the following columns: Date, X1, Y1, Z1, X2, Y2, Z2... Xn, Yn, Zn.
When populated, Date ALWAYS has a value, and X/Y/Z1 to X/Y/Zn can be DBNull, a string, or an int. If the entire row with the exception of Date, is DBNull, i would like to remove that particular row.
I am currently doing an exhaustive search, looping through each row with a for loop, and then with a nested for loop, checking each cell, if i do not find any data (ie. only dbnull's), i then call RemoveAt, and reset the outer loop to start at zero again.
Is there a better/less hacky way of performing this operation? The initial building of the datatable cannot be modified, this must be something that happens post building.
If I understand correctly, you want to remove a row if all columns has DbNull.Value.
Try the following to do that.
DataTable table = new DataTable();
string[] columns = table.Columns.Cast<DataColumn>()
.Select(x => x.ColumnName)
.Skip(1)//skip to ignore first column
.ToArray();
Method1:
Remove all invalid rows
var invalidRows = table.AsEnumerable()
.Where(x => columns.All(c => x.Field<object>(c) == DBNull.Value))
.ToArray();
foreach (var row in invalidRows)
{
table.Rows.Remove(row);
}
Method2: take only valid rows and make new DataTable as suggested my #Tim in comments to improve performance when you have many invalid rows
var newTable = table.AsEnumerable()
.Where(x => columns.Any(c => x.Field<object>(c) != DBNull.Value))
.CopyToDataTable();
ATTENTION : THESE ARE MY EXAMPLES>>NOT EXCATLLY FOR YOUR TABLE>>>SO CHANGE IT FOR YOURSELF
The Main Help is Here >> Help
And Then
Way one :
dtData.Select("ID=1 AND ID2=3");
Way two :
GridFieldDAO dao = new GridFieldDAO();
//Load My DataTable
DataTable dt = dao.getDT();
//Get My rows based off selection criteria
DataRow[] drs = dt.Select("(detailID = 1) AND (detailTypeID = 2)");
//make a new "results" datatable via clone to keep structure
DataTable dt2 = dt.Clone();
//Import the Rows
foreach (DataRow d in drs)
{
dt2.ImportRow(d);
}
//Bind to my new DataTable and it will only show rows based off selection
//criteria
myGrid.DataSource = dt2;
myGrid.DataBind();
And The best Way is :
DataTable tblFiltered = table.AsEnumerable()
.Where(row => row.Field<String>("Nachname") == username
&& row.Field<String>("Ort") == location)
.OrderByDescending(row => row.Field<String>("Nachname"))
.CopyToDataTable();
May be this will help you. Try this
var ordered = yourdatatable.AsEnumerable().Where(x => x.Field<DateTime>("ColumnName") != null);
if (ordered.Count() > 0)
{
yourdatatable= orderedCopyToDataTable();
}
you can do the same for other columns as well.
Or
Why don't you check for the null values in your query. check for ISNULL(columnName, value) As ColumnName. Check more details here
You can use this little Linq query:
var columnsWithoutDate = table.Columns.Cast<DataColumn>().Skip(1);
table = table.AsEnumerable()
.Where(row => columnsWithoutDate.Any(col => !row.IsNull(col)))
.CopyToDataTable();
Skip(1) returns all columns but the first, so your date column is excluded. The Where enumerates all DataRows in the table and takes all rows with at least one non-null field(see:DataRow.IsNull(column)). Finally CopyToDataTable creates a new DataTable.
I would go for something like this:
var test = from row in table.AsEnumerable()
where (!row.IsNull("col1") || !row.IsNull("col2"))
select row;
//option1
DataTable dt = test.CopyToDataTable<DataRow>();
//option2
DataTable dt2 = new DataTable();
dt2.Columns.Add("col1", typeof(String));
dt2.Columns.Add("col2", typeof(Int32));
foreach (var v in test)
{
DataRow dr = dt2.NewRow();
dr["col1"] = v.Field<String>("col1");
dr["col1"] = v.Field<Int32>("col2");
dt2.Rows.Add(dr);
}
Did you try using RowFilter of DataTable?
DataTable dt = GetData();
//set the filter
dt.DefaultView.RowFilter = "----your filter----";
//then access the DataView
foreach (DataRowView drv in dt.DefaultView)
{
//you can also get a row from rowview
DataRow dr = drv.Row;
}
Check this documentation, they also explain how to handle null values in filters.
http://msdn.microsoft.com/en-us/library/system.data.dataview.rowfilter.aspx
You can also use Select() method with same filter, refer the below answer there is a good comparison on both approach.
DataView.RowFilter Vs DataTable.Select() vs DataTable.Rows.Find()
I would not suggest using AsEnumerable() approach, though looks like simple code but it is just like doing a foreach loop on rows and having IF conditions.
DataTable filter approach should be faster than AsEnumerable() (I am not sure, but I am assuming this because DataTable is .net's powerful data structure to handle tabular data)
modified answer:
myDataTable.AsEnumerable().Where(a => a.ItemArray.Count(b=>b != DBNull.Value)==1).ToList().ForEach(row => dataTable.Rows.Remove(row));
I checked, it works.
EDIT:
in response to #Tim Schmelter comment:
1 . you need myDataTable.AsEnumerable() in C#
If you have a strongly typed DataTable, you do not. I assumed it's the case, since OP says:
The initial building of the datatable cannot be modified, this must be
something that happens post building.
Maybe I did't understand what he meant (my English sometimes fails me)
2 . count the non-null fields is incorrect since a string can be null
which is not the same as if it is DBNull.Value(also according OP's
specifications)
You are probably right. If OP says he only wants DBNull, the second condition should be removed (it's a bad habit of mine to check for null just in case)
3 . ToList creates another List which is redundant
Yes. And if there's no ToList(), ForEach() can't be used. The old fashioned foreach can be used instead, or beter for loop (since foreach doesn't like when you try to modify collection inside it). Still you have to keep your result in some way.
4 . DataRow.Delete does it not remove from the table what is desired,
but it flags it as deleted for a DataAdapter(OP's has not mentioned
that he's using one, it is also not desired).
Thank you for pointing that out.
How do filter a empty String in DataTable?
I need to filter a column (say Customer Name where the name is string.Empty)
I tried this but i cant get into right way..
I need to filter the DataView through DataView.RowFilter.. so how to give filter string for string.Empty..
Any idea on this?
To filter a dataTable-
dt.Select("customer_name = ''");
To Filter datatview-
dv.RowFilter = "customer_name = ''";
Use Select method:
DataRow[] foundRows = dt.Select("MyColumn = ''");
You can use Select method for DataTable:
//selects all customers which name is empty
var rows = dtData.Select("CustomerName = ''");
See the code below, might be a help. I am answering as the question has a tag RowFilters
private void GetRowsByFilter()
{
DataTable table = DataSet1.Tables["YourTable"];
// Presuming the DataTable has a column named Date.
string expression = "Column_name = ''";
// Sort descending by column named CompanyName.
string sortOrder = "ColumnName DESC";
DataRow[] foundRows;
// Use the Select method to find all rows matching the filter.
foundRows = table.Select(expression, sortOrder);
// Print column 0 of each returned row.
for(int i = 0; i < foundRows.Length; i ++)
{
Console.WriteLine(foundRows[i][0]);
}
}
Try below code:
DataTable dt=new DataTable();
DataRow dr;
dr=dt.NewRow();
if(dr["CustomerName"]==null)
{
put some code here.........
}
i Hope This code will help 4 u
I'm running a LINQ query on a datatable in c#.
I want to select specific columns rather than the whole row and enter the result into a datatable. How can i do that??
My Code:
public DataTable getConversions(string c_to, string p_to)
{
var query = from r in matrix.AsEnumerable()
where r.Field<string>("c_to") == c_to &&
r.Field<string>("p_to") == p_to
select r;
DataTable conversions = query.CopyToDataTable();
If you already know beforehand how many columns your new DataTable would have, you can do something like this:
DataTable matrix = ... // get matrix values from db
DataTable newDataTable = new DataTable();
newDataTable.Columns.Add("c_to", typeof(string));
newDataTable.Columns.Add("p_to", typeof(string));
var query = from r in matrix.AsEnumerable()
where r.Field<string>("c_to") == "foo" &&
r.Field<string>("p_to") == "bar"
let objectArray = new object[]
{
r.Field<string>("c_to"), r.Field<string>("p_to")
}
select objectArray;
foreach (var array in query)
{
newDataTable.Rows.Add(array);
}
Try Access DataTable easiest way which can help you for getting perfect idea for accessing DataTable, DataSet using Linq...
Consider following example, suppose we have DataTable like below.
DataTable ObjDt = new DataTable("List");
ObjDt.Columns.Add("WorkName", typeof(string));
ObjDt.Columns.Add("Price", typeof(decimal));
ObjDt.Columns.Add("Area", typeof(string));
ObjDt.Columns.Add("Quantity",typeof(int));
ObjDt.Columns.Add("Breath",typeof(decimal));
ObjDt.Columns.Add("Length",typeof(decimal));
Here above is the code for DatTable, here we assume that there are some data are available in this DataTable, and we have to bind Grid view of particular by processing some data as shown below.
Area | Quantity | Breath | Length | Price = Quantity * breath *Length
Than we have to fire following query which will give us exact result as we want.
var data = ObjDt.AsEnumerable().Select
(r => new
{
Area = r.Field<string>("Area"),
Que = r.Field<int>("Quantity"),
Breath = r.Field<decimal>("Breath"),
Length = r.Field<decimal>("Length"),
totLen = r.Field<int>("Quantity") * (r.Field<decimal>("Breath") * r.Field<decimal>("Length"))
}).ToList();
We just have to assign this data variable as Data Source.
By using this simple Linq query we can get all our accepts, and also we can perform all other LINQ queries with this…
Here I get only three specific columns from mainDataTable and use the filter
DataTable checkedParams = mainDataTable.Select("checked = true").CopyToDataTable()
.DefaultView.ToTable(false, "lagerID", "reservePeriod", "discount");
LINQ is very effective and easy to use on Lists rather than DataTable. I can see the above answers have a loop(for, foreach), which I will not prefer.
So the best thing to select a perticular column from a DataTable is just use a DataView to filter the column and use it as you want.
Find it here how to do this.
DataView dtView = new DataView(dtYourDataTable);
DataTable dtTableWithOneColumn= dtView .ToTable(true, "ColumnA");
Now the DataTable dtTableWithOneColumn contains only one column(ColumnA).
Your select statement is returning a sequence of anonymous type , not a sequence of DataRows. CopyToDataTable() is only available on IEnumerable<T> where T is or derives from DataRow. You can select r the row object to call CopyToDataTable on it.
var query = from r in matrix.AsEnumerable()
where r.Field<string>("c_to") == c_to &&
r.Field<string>("p_to") == p_to
select r;
DataTable conversions = query.CopyToDataTable();
You can also implement CopyToDataTable Where the Generic Type T Is Not a DataRow.