DataRow[] headerRows = null;
headerRows = mappingTable.Select("FieldID LIKE '0_%'"); //mappingTable is of type DataTable.
I have three columns in the mappingTable "Id","Display", "Value"
Now, I need to get the Value where "Id" = 0_0_0 from the headerRows.
Is there any simple way to do this?
Thanks for any help.
If you have to use DataRow[] then with linq you can do this:
String value = (String)rows.Single(
row => String.Equals(row["Id"], "0_0_0"))["Value"];
You need to set the PrimaryKey on the DataTable and then you can use Find() on the Rows collection to find the row with that key.
dataTable.PrimaryKey = new DataColumn[] { dataTable.Columns["Id"] };
object value = dataTable.Rows.Find("0_0_0")["Value"];
You could use LINQ: but this might be overkill:
dt.AsEnumerable().Where(dr => dr.Field<object>("FieldId").StartsWith("0_"));
If you have to have DataRow[] then
headerRows = dt.AsEnumerable().Where(dr => dr.Field<object>("FieldId").StartsWith("0_")).ToArray();
From there you have only data rows that match your criteria, so you can cycle through for the value.
Related
In my form I have this DataGridView (grid1), filled from a sqllite database.
I want select the column with the name "cap" and insert the column's values into an array.
How can I do?
I don't find a way to select the column cap by name, so I decided to indicate it with the index, but I don't like this way..
I don't know ho to insert these values into an array. there are a lot of columns/cell method but I don't figured out which one can help me!
I tryed to do this way (from an old answer here in the site) but it gives me error of "out of bounded matrix"
int[] wareCap = new int[grid1.Rows.Count];
...
//How I filled my dgv, if this can help
var context = new ForliCesenaEntities2();
BindingSource bi1 = new BindingSource();
bi1.DataSource = context.warehouses.ToList();
grid1.DataSource = bi1;
grid1.Refresh();
//How I try to insert the values into int[] wareCap
for (int i = 0; i<(grid1.Rows.Count-1); i++)
wareCap[i] = Convert.ToInt16(grid1.Rows[i].Cells[1].Value);
Thanks in advice
First you gridview has to be filled with values, then:
List<int> intValues = new List<int>();
foreach (DataGridViewRow row in grid.Rows)
{
intValues.Add(int.Parse(row.Cells["cap"].Value.ToString()));
}
int[] array = intValues.ToArray();
should do the trick.
Alternatively, you could use LINQ.
int[] intArray = dataGridView1.Rows
.Cast<DataGridViewRow>()
.Select(row => int.Parse(row.Cells["cap"].Value.ToString())).ToArray();
UPDATE:
The above solution might crash if the DataGridView's AllowUserToAddRows property is set to true. Because in that case your last row is the row for entering a new record, the Value is null, so invoking the ToString method on it causes a NullReferenceException.
I see two possibilities:
set your datagridview's AllowUserToAddRows property to false (but the user won't be able to add new rows),
use the following solution
Check if the row is the row for entering a new record:
int[] intArray = dataGridView1.Rows
.Cast<DataGridViewRow>()
.Where(row => !row.IsNewRow)
.Select(row => Convert.ToInt32(row.Cells["cap"].Value.ToString())).ToArray();
You already got all your values in a List, because you do sth. like this:
bi1.DataSource = context.warehouses.ToList();
You can easily store this in a reference:
var values = context.warehouses.ToList();
bi1.DataSource = values;
Your Grid is build based on Objekts in this List. So this should build your array:
int[] array = new int[values.Count];
int counter = 0;
foreach (var object in values)
{
array[counter++] = object.CAP;
}
int[] wareCap = new int[grid1.Rows.Count];
foreach(DataGridViewRow row in grid1.Rows)
{
wareCap.Add(Convert.ToInt32(cell["cap"].Value.ToString()));
}
I have a DataTable. I want to get every rows first column value and append to a string array. I do not want to use foreach looping for every row and adding to string array. I tried this, but stuck at some point
DataRow[] dr = new DataRow[dtCampaignSubscriberLists.Rows.Count];
dtCampaignSubscriberLists.Rows.CopyTo(dr, 0);
string[] array = Array.ConvertAll(dr, new Converter<DataRow, String>(????));
Thanks
string[] array = yourTable
.AsEnumerable()
.Select(row => row.Field<string>("ColumnName"))
.ToArray();
You could do something like:
dtCampaignSubscriberLists.AsEnumerable().Select(r => r[0].ToString()).ToArray();
EDIT: Solved this myself - obviously won't work as sorting the dataTable doesn't sort the underlying data - created a dataView from the table, works fine.
I have a datatable which I am sorting and then iterating through to remove duplicate values in one column, however the output is not as expected.
Datatable structure:
infoRow["Title"]
infoRow["QuickLink"]
infoRow["Description"]
infoRow["Date"]
infoRow["MonthName"]
I'm sorting like this, which works fine, and produces a table ordered in ascending month order:
dataTable = dataTable.DefaultView.ToTable(true);
dataTable.DefaultView.Sort = "Date asc";
After the sort, I'm using the code below to compare each row to the previous, and if the MonthName value is the same, replaced it with an empty string:
string prevMonthName = "";
foreach (DataRow row in dtEvents.Rows)
{
string strMonthName = row["MonthName"].ToString();
if (strMonthName == prevMonthName)
{
row["MonthName"] = "";
row.AcceptChanges();
}
prevMonthName = strMonthName;
}
So, the problem I'm having is that even when I run the MonthName loop after the sort, it appears to be running against the unsorted data. It's like DefaultView.Sort only affects the rendered output without physically reordering the table, hence the second part of the code doesn't produce the result I need. Should I maybe be using DataView or am I just way off track...
I was actually having a similar, but slightly different problem and your question gave me an idea. As it turns out, your code was incredibly close to what you (and I) need. All you need to do is flip those two lines of sorting code like so:
dataTable.DefaultView.Sort = "Date ASC";
dataTable = dataTable.DefaultView.ToTable(true);
Now, the first line of code sorts the DefaultView. This would be enough for your DataGridView or ComboBox or whatever you're using for display, because they make use of the DefaultView. However, the DataTable, itself, remains unsorted. Therefore, the second line sets the DataTable to look exactly like the sorted DefaultView.
I just noticed your edit at the top which says you've solved it. That 'solution' seems to be more of a workaround. Seeing as how you had the right code but in the wrong order, I figured you would be interested in this answer.
Assuming that dtEvents is referencing the same object as datatable, you could try this:
string prevMonthName = "";
foreach (DataRowView row in dtEvents.DefaultView)
{
string strMonthName = row["MonthName"].ToString();
if (strMonthName == prevMonthName)
{
row["MonthName"] = "";
row.AcceptChanges();
}
prevMonthName = strMonthName;
}
Just for fun I figured out how to do this using Linq to SQL (assuming I had a sql table with your above schema). Since I spent the time figuring it out, I thought I might as well share it.
// Order the table and add an index column
var ordered = MonthTests.OrderBy(mt => mt.Date)
.AsEnumerable()
.Select((mt, index) => new
{
OrderId = index,
Record = mt
});
// Select out what we want
var query = from item in ordered
let prev = ordered.FirstOrDefault (q => q.OrderId == (item.OrderId-1))
select new
{
Title = item.Record.Title,
QuickLink = item.Record.QuickLink,
Date = item.Record.Date,
MonthName = (prev != null && prev.Record.MonthName == item.Record.MonthName) ? "" : item.Record.MonthName
};
Have fun.
I have a database column I simply need to check to see if a value is there.
DataTable dt = masterDataSet.Tables["Settings"];
DataColumn SETTINGS = dt.Columns["DEFAULTSETTINGS"];
I just need to iterate over the values in this column to see if a value exists.
Help
You iterate the rows, not the column
DataColumn SETTINGS = dt.Columns["DEFAULTSETTINGS"];
foreach(DataRow row in dt.Select())
{
object columnValue = row[SETTINGS];
// Do something with columnValue
}
There's no need to use Linq or iterate manually through your DataRows as plain old ADO.NET has a couple of solutions such as DataTable.Select and DataView.RowFilter.
string value = "default";
bool found = dt.Select("DEFAULTSETTINGS = " + value).Length > 0;
It's obvious that once you get the filtered rows, you can do whatever you want with them. In my example, I just checked to see if any row was within the criteria but you can manipulate them how you see fit.
You can use linq in .net 3.5:
DataColumn col = dt.Columns["DEFAULTSETTINGS"];
object value = //expected value
bool valueExists = dt.AsEnumerable().Any(row => row.Field<object>(col).Equals(value));
EDIT: It seems from the comments you're trying to see if the 'DEFAULTSETTINGS' column contains the string 'default'. The Field extension method simply casts the object in the datarow at that column into the given type, so you can change the type parameter rather than use ToString(). So for your example you can probably use this:
DataColumn col = dt.Columns["DEFAULTSETTINGS"];
bool valueExists = dt.AsEnumerable().Any(row => "default".Equals(row.Field<string>(col), StringComparison.OrdinalIgnoreCase);
How to do following scenario:
I have some DataTable which contains for example some rows:
1.rowa
2.rowab
3.row
4.rowaba
...
n. rowabba
How to sort rows by lenght, not by name. I wan to to sort Table by length of fields.
You could add an extra column to your DataTable, supplying an expression containing a call to the len() function, causing the column's values to be automatically computed:
table.Columns.Add("LengthOfName", typeof(int), "len(Name)");
Then you can simply sort on your new column before binding the DataTable to a grid to whatever kind of UI control you plan to use:
table.DefaultView.Sort = "LengthOfName";
If you must use DataTable, you could introduce an extra column for the sort. In this case, you could set the value in the column simply to the length of each desired cell, and then sort by the new column:
DataTable table = new DataTable();
DataColumn val = table.Columns.Add("Value", typeof(string));
table.Rows.Add("abc");
table.Rows.Add("defgh");
table.Rows.Add("i");
table.Rows.Add("jklm");
// sort logic: ***** schou-rode's "len(...)" approach is better *****
DataColumn sort = table.Columns.Add("Sort", typeof(int));
foreach (DataRow row in table.Rows) {
row[sort] = ((string)row[val]).Length;
}
DataView view = new DataView(table);
view.Sort = "Sort";
foreach (DataRowView row in view) {
Console.WriteLine(row.Row[val]);
}
Personally, I'd use a typed list - of either a class, or a string in this case (since you only list one value):
List<string> list = new List<string> {
"abc", "defgh", "i", "jklm"};
list.Sort((x, y) => x.Length.CompareTo(y.Length));
foreach (string s in list) {
Console.WriteLine(s);
}