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);
}
Related
I have below class with one property.
public class MfrYearEqpType
{
public string EqpType { get; set; }
public MfrYearEqpType()
{
}
}
I wanted to create dynamic properties(Datatable column names) to my class "MfrYearEqpType" and set the values from below Datatable.
DataTable dt = getData();
This table contains 26 rows and 10 columns of data.
I have gone through the below link. But I am not sure how to handle my case.
Dynamically adding properties to an Object from an existing static object in C#
And also I have used ExpandoObject. I have done below sample.
DataTable dt = getData();
List<dynamic> expandoList = new List<dynamic>();
foreach (DataRow row in dt.Rows)
{
//create a new ExpandoObject() at each row
var expandoDict = new ExpandoObject() as IDictionary<String, Object>;
foreach (DataColumn col in dt.Columns)
{
//put every column of this row into the new dictionary
expandoDict.Add(col.ToString(), row[col.ColumnName].ToString());
}
//add this "row" to the list
expandoList.Add(expandoDict);
}
But my aim is to create the List of MfrYearEqpType. So that I can bind List of MfrYearEqpType to Gridview.
Please help me on this.
Assuming you are talking about ASP.NET here, you can directly bind your data table to a GridView's DataSource property.
If you are happy with these 10 columns displaying as default, you can set AutoGenerateColumns property to true. Otherwise, you may want to define <asp:BoundField /> or <asp:TemplateField /> columns as appropriate. Bound fields will let you at least format the value for a particular column while template fields will allow full customization where you can provide an defining how to render a particular field.
I have seen the following solution used for removing duplicate rows in a DataTable using LINQ:
Say if we have a DataTable with duplicate rows called dt, then the following statemend apparently does the job:
IEnumerable<DataRow> uniqueContacts = dt.AsEnumerable().Distinct(DataRowComparer.Default);
But this is only removing duplicate rows that are identical. What I want to do is to remove all the rows that have duplicate values of a specific row.
E.g. If we have a datatable with a row called "Email", how can we remove all the rows that have the same email value?
simple way: use GroupBy:
var uniqueContacts = dt.AsEnumerable()
.GroupBy(x=>x.Field<string>("Email"))
.Select(g=>g.First());
you can also try use Distinct:
DataTable dt = new DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("FirstName");
dt.Columns.Add("Email");
dt.Rows.Add(1,"Tim","tim#mail.com");
dt.Rows.Add(2,"Tim1","tim#mail.com");
dt.Rows.Add(3,"Tim2","tim2#mail.com");
dt.Rows.Add(4,"Tim3","tim3#mail.com");
dt.AsEnumerable().Distinct(new DataRowComparer()).Dump();
Custom row comparer:
public class DataRowComparer : IEqualityComparer<DataRow>
{
public bool Equals(DataRow t1, DataRow t2)
{
return (t1.Field<string>("Email")==t2.Field<string>("Email"));
}
public int GetHashCode(DataRow t)
{
return t.ToString().GetHashCode();
}
}
http://msdn.microsoft.com/en-us/library/bb338049.aspx
I created a class library and I am trying to add data from a List<string[]> to a DataGridView.
The string is in the format as follows:
"Test, 1^Glucose^10/24/2013 10:00;Test, 2^BUN^10/25/2013 11:00;Test, 3^BUN^10/25/2013 11:00"
I am passing the string from another program. I then an making it into a list and then trying to add it to the DataTable but no such luck. I created the datagridview with four columns.
Selected - Checkbox
Patient Name - String
Order Name - String
Order Date - String
Reason - Combo Box
I am getting an error:
the list is greater than the number of columns.
Note: I can make the string anyway I want before passing to this program so if I need to do something with the string before passing it to the program, please let me know. Is there an easier way?
I just want the data to display and I will work on the rest of it.
Any help would be appreciated.
This is my code:
public partial class RenewOrders : Form
{
public static string strMLMPatientData = string.Empty;
public RenewOrders(string all_patient_data)
{
InitializeComponent();
strMLMPatientData = "Test, 1^Glucose^10/24/2013 10:00;Test, 2^BUN^10/25/2013 11:00;Test, 3^BUN^10/25/2013 11:00"
}
private void RenewOrders_Load(object sender, EventArgs e)
{
this.ConvertStringToList(strMLMPatientData);
}
private void ConvertStringToList(string strMLMPatientData)
{
var patient_list = strMLMPatientData.Split(';').Select(x => x.Split('^')).ToList();
DataTable dtTable = ConvertListToDataTable(patient_list);
dataGridView1.DataSource = dtTable;
}
// Convert to DataTable.
static DataTable ConvertListToDataTable(List<string[]> patient_list)
{
// New table.
DataTable dtTable = new DataTable();
dtTable.Columns.Add("Name", typeof(string));
dtTable.Columns.Add("Order Name", typeof(string));
dtTable.Columns.Add("Order Date/Time", typeof(string));
foreach (var row in patient_list)
{
table.Rows.Add(row);
}
return dtTable;
}
}
First you need to spit the string appropriately to get a list of string arrays. Something like this:
var patient_list = new List<string[]>(strMLMPatientData.Split(';').Select(x => x.Split(',')));
or even better:
var patient_list = strMLMPatientData.Split(';').Select(x => x.Split(',')).ToList();
You need Linq for that, but you get the idea.
Then you need to add columns to your data table. You cant add rows to it when there are no columns..
Try something like this in your function
//add columns appropriately
DataTable table = new DataTable();
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Order", typeof(string));
table.Columns.Add("Date", typeof(string));
foreach (var row in patient_list)
table.Rows.Add(row);
return table;
See an example here. As it stands, your comma separated input string doesnt seem to match your data table column structure. You need to work it out. But I hope you got the idea which way to go.
I want to extract a value from the datatable and store to a collection. What would be the best way to do it?
The rows in my Datatable will have data like :
Row 1 <configuration><Store parameter="Atribs">AB,CD</Store></configuration>
Row 2 <configuration><Store parameter="Atribs">EF,GH,IJ</Store></configuration>
......
I want to retrieve and store the values in a collection like,
Collection 1 :
AB
CD
Collection 2 :
EF
GH
IJ
Collection ....
Here you go...
var table = new DataTable();
var column = new DataColumn("col1");
table.Columns.Add(column);
var row = table.NewRow();
row[0] = #"<configuration><Store parameter=""Atribs"">AB,CD</Store></configuration>";
table.Rows.Add(row);
row = table.NewRow();
row[0] = #"<configuration><Store parameter=""Atribs"">EF,GH,IJ</Store></configuration>";
table.Rows.Add(row);
var data = new List<List<string>>();
foreach (DataRow dRow in table.Rows)
{
var temp = new List<string>();
string xml = dRow.Field<string>("col1");
var element = XElement.Parse(xml);
string[] values = element.Descendants("Store").First().Value.Split(',');
temp.AddRange(values);
data.Add(temp);
}
You say a DataTable, but provided xml data in your example, so I am not sure.. bu basically, this is what you need to do:
var myList = new List<string>();
foreach (DataRow row in dataTable.Rows)
{
myList.Add(row.Field<string>("myCol"));
}
Something like that. It would be easier to give a better example if you could provide us with info about your DataTable and not your source xml file. :)
You might need to be a bit more clear on what you mean by "datatable" in that your example data is XML. Provided you know enough to fetch the rows from the data/xml:
Read each row and use String.Split() on the inner value to generate a string array which can be fed into a List.
var list = new List<string>(String.Split(",", innerData));
Of course you'll want to validate that the inner data has content.
I've got a DataTable with this fields
datatable.Columns.Add("ProductID", typeof(int));
datatable.Columns.Add("LocationList", typeof(List<string>));
datatable.Columns.Add("LocationIds", typeof(List<int>));
datatable.Columns.Add("ProductName", typeof(string));
datatable.Columns.Add("Brand", typeof(string));
datatable.Columns.Add("Price", typeof(decimal));
datatable.Columns.Add("Quantity", typeof(int));
datatable.Columns.Add("Locations", typeof(string));
And I bind it to a ListView
foreach (DataRow row in productsDataTable.Rows)
{
var item = new ListViewItem(row[0].ToString());
for (var i = 1; i < productsDataTable.Columns.Count; i++)
item.SubItems.Add(row[i].ToString());
lvSearchResults.Items.Add(item);
}
I want to bind the List<> fields, so that when a row is selected, I'd be able to get the data from the Lists and do some calculations with it.
Is there any way to do this?
The ListViewItem has a Tag property that you can store data in to retrieve and use later, for example:
foreach (DataRow row in productsDataTable.Rows)
{
var item = new ListViewItem(row[0].ToString());
// Store the specific values you want to later retrieve
item.Tag = new object[] { row["LocationList"], row["LocationIds"] };
// Or, store the whole row
item.Tag = row;
lvSearchResults.Items.Add(item);
}
The ListViewItem.Tag property allows you to associate anything you want with the item. You could store the entire DataRow in there and retrieve any columns you want.