I need to add columns from one datatable to another only if the columns in second datable not exists and also the second datatable has expression column that needs to set value from first datatable column using linq.
I have achieved this using foreach but how to do without foreach in linq ?
DataTable first = new DataTable();
first.Clear();
first.Columns.Add("Name");
first.Columns.Add("Exp");
DataRow _ra = dt1.NewRow();
_ra["Name"] = "Column_1";
_ra["Exp"] = "ExpTarget * Column_3";
first.Rows.Add(_ra);
DataRow _r = dt1.NewRow();
_r["Name"] = "Column_2";
_r["Exp"] = "ExpTarget * Column_3";
first.Rows.Add(_r);
DataRow _r2 = dt1.NewRow();
_r2["Name"] = "Column_3";
_r2["Exp"] = "ExpTarget";
first.Rows.Add(_r2);
DataTable second = new DataTable();
second.Clear();
second.Columns.Add("Column_3",typeof(System.Int16));
second.Columns.Add("ExpTarget",typeof(System.Int16));
DataRow _r21 = table.NewRow();
_r21["Column_3"] = 100;
_r21["ExpTarget"] = 2;
second.Rows.Add(_r21);
Code to add columns & expression is below, i need to avoid foreach linq below for expression column, how to do it without foreach ?
// get all columns from first datatable
string[] col = string.Join(",", first.AsEnumerable().Select(x => x["Name"].ToString()).ToArray()).Split(',').ToArray();
// get all columns and expression from first datatable
List<string> exp = string.Join(",", first.AsEnumerable().Select(x => x["Name"].ToString() + "~" + x["Exp"].ToString()).ToArray()).Split(',').ToList();
List<string[]> list = new List<string[]>();
list.Add(col);
second.Columns.AddRange(list.First().Select(r => second.Columns.Contains(r) ? second.Columns["Dummy"] : new DataColumn(r, typeof(System.Decimal))).ToArray());
exp.ForEach(r =>
{
second.Columns[r.ToString().Split('~')[0].ToString()].Expression = r.ToString().Split('~')[1].ToString();
});
For a test I'm trying to write, all I need is a DataTable with 1 row with ["foo"] = 2314 so that I reach the body of the loop
foreach(DataRow row in mockDataTable.Rows)
{
// ...
int val = (int)row["foo"];
// ...
}
inside a method that my test is testing.
However I can't figure out how to do this through the documentation on https://msdn.microsoft.com/en-us/library/system.data.datatable(v=vs.110).aspx
var dt = new DataTable();
dt.Columns.Add("foo", typeof (int));
var row = dt.NewRow();
row["foo"] = 1234;
dt.Rows.Add(row);
I have a DataTable with two columns: File & Email
C://file1.jpg aaa#gmail.com
C://file2.jpg aaa#gmail.com
C://file3.jpg bbb#gmail.com
C://file4.jpg ccc#gmail.com
C://file5.jpg bbb#gmail.com
In my code i loop through the DataRows and send an email to Email with File attached.
Problem:
I need to somehow check if there are any other DataRows with the same Email and if so, send just one email with multiple attachments.
So the above DataTable would result in 3 emails:
file1,file2 sent to aaa#gmail.com
file3,file5 sent to bbb#gmail.com
file4 sent to ccc#gmail.com
My code sample:
foreach (DataRow row in dt.Rows) {
string file = row[0].ToString();
string email = row[1].ToString();
SendEmailWithAttachments(email,file);
}
I could pass a StringCollection or an array to my SendEmailWithAttachments() function then loop throught it and attach all the files, but how do I group these DataRows in first place
Using the GroupBy Linq extension you could handle your DataRows grouping them for the Email field, then foreach create a list of strings with the file names.
Of course, you need also to change the SendMailWithAttachments to receive as second parameter a List<string> instead of a single string
var g = dt.AsEnumerable().GroupBy(d => d.Field<string>("Email"));
foreach (var x in g)
{
List<string> files = new List<string>();
foreach (var z in x)
files.Add(z.Field<string>("File"));
SendEmailWithAttachments(email,files);
}
You could use GroupBy to group by email:
DataTable dt = new DataTable();
dt.Columns.Add("Path");
dt.Columns.Add("Email");
DataRow dr = dt.NewRow();
dr.ItemArray=new object[2]{"C://file1.jpg", "aaa#gmail.com"};
dt.Rows.Add(dr);
dr = dt.NewRow();
dr.ItemArray=new object[2]{"C://file2.jpg", "aaa#gmail.com"};
dt.Rows.Add(dr);
dr = dt.NewRow();
dr.ItemArray=new object[2]{"C://file3.jpg", "bbb#gmail.com"};
dt.Rows.Add(dr);
dr = dt.NewRow();
dr.ItemArray=new object[2]{"C://file4.jpg", "ccc#gmail.com"};
dt.Rows.Add(dr);
dr = dt.NewRow();
dr.ItemArray=new object[2]{"C://file5.jpg", "bbb#gmail.com"};
dt.Rows.Add(dr);
var grouped=dt.AsEnumerable().GroupBy(x=>x.Field<string>("Email"));
foreach (var mail in grouped)
{
List<string> filesForEmail = new List<string>();
foreach (var file in mail)
{
filesForEmail.Add(file.Field<string>("Path"));
}
SendEmailWithAttachments(mail.Key, filesForEmail);
}
I`m trying to use something like this:
I have 20 list items and I have to choose some of them, then add them to datatable in first column elements, in second - their indexes.
DataTable dt = new DataTable();
dt.Columns.Add("Фактор-Критерій", typeof(string));
dt.Columns.Add("Ранг", typeof(string));
ChoosenCriteria.DataSource = dt;
List<string> selectedItems = new List<string>();
foreach (string o in listBox1.SelectedItems)
selectedItems.Add(o);
List<int> selectedItemIndexes = new List<int>();
foreach (int o in listBox1.SelectedIndices)
selectedItemIndexes.Add(listBox1.Items.IndexOf(o));
DataRow dr = dt.NewRow();
dr[0] = selectedItems.ToString();
dr[1] = selectedItemIndexes.ToString();
dt.Rows.Add(dr););
I can not do this, all i have at the end is on screen:enter image description here
Move the DataSource binding statement after you have done with the modification like
for(int i=0; i<selectedItems.Count;i++
{
DataRow dr = dt.NewRow();
dr[0] = selectedItems[i].ToString();
dr[1] = selectedItemIndexes[i].ToString();
dt.Rows.Add(dr);
}
ChoosenCriteria.DataSource = dt;
I want to convert a DataRow array into DataTable ... What is the simplest way to do this?
For .Net Framework 3.5+
DataTable dt = new DataTable();
DataRow[] dr = dt.Select("Your string");
DataTable dt1 = dr.CopyToDataTable();
But if there is no rows in the array, it can cause the errors such as The source contains no DataRows. Therefore, if you decide to use this method CopyToDataTable(), you should check the array to know it has datarows or not.
if (dr.Length > 0)
DataTable dt1 = dr.CopyToDataTable();
Reference available at MSDN:
DataTableExtensions.CopyToDataTable Method (IEnumerable)
Why not iterate through your DataRow array and add (using DataRow.ImportRow, if necessary, to get a copy of the DataRow), something like:
foreach (DataRow row in rowArray) {
dataTable.ImportRow(row);
}
Make sure your dataTable has the same schema as the DataRows in your DataRow array.
DataTable dt = new DataTable();
DataRow[] dr = (DataTable)dsData.Tables[0].Select("Some Criteria");
dt.Rows.Add(dr);
Another way is to use a DataView
// Create a DataTable
DataTable table = new DataTable()
...
// Filter and Sort expressions
string expression = "[Birth Year] >= 1983";
string sortOrder = "[Birth Year] ASC";
// Create a DataView using the table as its source and the filter and sort expressions
DataView dv = new DataView(table, expression, sortOrder, DataViewRowState.CurrentRows);
// Convert the DataView to a DataTable
DataTable new_table = dv.ToTable("NewTableName");
Simple way is:
// dtData is DataTable that contain data
DataTable dt = dtData.Select("Condition=1").CopyToDataTable();
// or existing typed DataTable dt
dt.Merge(dtData.Select("Condition=1").CopyToDataTable());
DataTable Assetdaterow =
(
from s in dtResourceTable.AsEnumerable()
where s.Field<DateTime>("Date") == Convert.ToDateTime(AssetDate)
select s
).CopyToDataTable();
DataTable dt = myDataRowCollection.CopyToDataTable<DataRow>();
DataTable dt = new DataTable();
foreach (DataRow dr in drResults)
{
dt.ImportRow(dr);
}
.Net 3.5+ added DataTableExtensions, use DataTableExtensions.CopyToDataTable Method
For datarow array just use .CopyToDataTable() and it will return datatable.
For single datarow use
new DataRow[] { myDataRow }.CopyToDataTable()
You could use System.Linq like this:
if (dataRows != null && dataRows.Length > 0)
{
dataTable = dataRows.AsEnumerable().CopyToDataTable();
}
Here is the solution. It should work fine.
DataTable dt = new DataTable();
dt = dsData.Tables[0].Clone();
DataRows[] drResults = dsData.Tables[0].Select("ColName = 'criteria');
foreach(DataRow dr in drResults)
{
object[] row = dr.ItemArray;
dt.Rows.Add(row);
}
Incase anyone needs it in VB.NET:
Dim dataRow as DataRow
Dim yourNewDataTable as new datatable
For Each dataRow In yourArray
yourNewDataTable.ImportRow(dataRow)
Next
You need to clone the structure of Data table first then import rows using for loop
DataTable dataTable =dtExisting.Clone();
foreach (DataRow row in rowArray) {
dataTable.ImportRow(row);
}
DataTable dataTable = new DataTable();
dataTable = OldDataTable.Tables[0].Clone();
foreach(DataRow dr in RowData.Tables[0].Rows)
{
DataRow AddNewRow = dataTable.AddNewRow();
AddNewRow.ItemArray = dr.ItemArray;
dataTable.Rows.Add(AddNewRow);
}