Linq in datatable or data set - c#

I have a list<string> and a DataSet. I need to write a Linq query to get the values from dataset or datatable to check if the values are present in List<string>. Please help me in writing the query to get datas from dataset or datatable
i will use foreach after getting the values to check whether the data is present in list<string>
EDIT:
DataSet dsDuplicate = (DataSet) Session["EventDescription"];
DataTable dt = dsDuplicate.Tables[0];
string cellValue = string.Empty;
for (int rowCount = 0; rowCount < gvEventMechanic.Rows.Count; rowCount++)
{
TextBox textBoxId = (TextBox)gvEventMechanic.Rows[rowCount].Cells[2].FindControl("txtId");
lstStringId.Add(textBoxId.Text);
}

List<string> list = ...
DataTable table = ...
var items = new HashSet<string>(list);
var results = from row in table.AsEnumerable()
where items.Contains(row.Field<string>("YourColumnName"))
select row;
foreach (var matchingRow in results)
{
// do whatever
}
Note: If you need the results to be in the form of another DataTable or DataView (such as for databinding), there are methods for that.
var output = results.CopyToDataTable(); // or
var output = results.AsDataView();

Related

How to match data from two data tables have single row using LINQ or C# other way

I have two data-table like below getting data from other datatables
DataTable dt
DataTable dt2
Datatable dt have below value and every time dt and dt2 have single row values only then easy match them
F1 F2 F3 F4
Yes No Yes No
Data-table dt2 have below value
F1 F2 F3
Yes Yes Yes
I want to match output like below into Data-table dt3, both on column name
F1 F3
Yes Yes
See datatable dt and datable dt2 both have only one row every time, so you can match dynamic because both have one row only with column name and value, so I not am getting how to match with dynamic using LINQ or some other way for better understanding please check the below image
If without linq is an option then you can try the below method:
public DataTable getMatchedColumnAndValue(DataTable dt1, DataTable dt2)
{
try
{
var ndt = new DataTable();
//creating columns for the table
var dt1columns = dt1.Columns.Cast<DataColumn>().Select(s => s.ColumnName).ToList();
var dt2columns = dt2.Columns.Cast<DataColumn>().Select(s => s.ColumnName).ToList();
var MatchedCol = dt1columns.Intersect(dt2columns).ToList();
foreach (var col in MatchedCol)
{
ndt.Columns.Add(col);
}
//creating columsn matcehd row
var drnew = new string[MatchedCol.Count];
for (int i = 0; i < MatchedCol.Count; i++)
{
if (dt1.Rows[0][MatchedCol[i]].ToString() == dt2.Rows[0][MatchedCol[i]].ToString())
drnew[i] = dt1.Rows[0][MatchedCol[i]].ToString();
else
drnew[i] = null;
}
ndt.Rows.Add(drnew);
//removing null value columns
foreach (var col in MatchedCol)
{
if (ndt.AsEnumerable().All(dr => dr.IsNull(col)))
ndt.Columns.Remove(col);
}
return ndt;
}
catch (Exception ex)
{
throw ex;
}
}
I believe someone might able to do better but here is mine. ※
Simplified the answer a bit.
private static DataTable RegenerateDataTableInCommon(DataTable dt, DataTable dt2)
{
var dtRows = dt.Rows.Cast<DataRow>();
var dt2Rows = dt2.Rows.Cast<DataRow>();
var dtColumnNames = dt.Columns.Cast<DataColumn>().Select(dtC => dtC.ColumnName);
var columnNameMatched = dt2.Columns.Cast<DataColumn>().Select(dtC => dtC.ColumnName).Where(colName => dtColumnNames.Contains(colName));
var cellValueMatched = columnNameMatched.Where(colName => dtRows.First()[colName] == dt2Rows.First()[colName]);
DataTable outDt = new DataTable();
outDt.Clear();
DataRow nRow = outDt.NewRow();
foreach (var colName in cellValueMatched)
{
outDt.Columns.Add(colName);
nRow[colName] = dtRows.First()[colName];
}
outDt.Rows.Add(nRow);
return outDt;
}

c# - DataTable expression column using linq

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();
});

Need help Creating a Datatable from a list with possible null values

I need some assistance in the best way to edit my DataTable to handle possible null values.
In this instance their is potential for any of the items from the list being added to the DataTable to be null. I'm looking for the best way to account for those null values when creating the DataTable so when I insert this into MSSQL I don't run into errors.
Here is the code I'm using to generate the DataTable:
public DataTable ConvertListToCustomDataTable(List<RootObject> listOfItems)
{
DataTable table = new DataTable();
table.Columns.Add("DateCreated");
table.Columns.Add("DepthCode");
table.Columns.Add("DepthDateCreated");
table.Columns.Add("DepthLevel");
table.Columns.Add("DepthID");
table.Columns.Add("DepthCategoryName");
table.Columns.Add("DepthName");
table.Columns.Add("DepthCategoryDateUpdated");
table.Columns.Add("DepthDateUpdated");
table.Columns.Add("Name");
table.Columns.Add("ID");
table.Columns.Add("CategoryCode");
table.Columns.Add("CategoryDateCreated");
table.Columns.Add("CategoryDateUpdated");
table.Columns.Add("CategoryID");
table.Columns.Add("CategoryName");
table.Columns.Add("Code");
foreach (var item in listOfItems)
{
var row = table.NewRow();
row["DateCreated"] = item.DateCreated;
row["DepthCode"] = item.Depth.Code;
row["DepthDateCreated"] = item.Depth.DateCreated;
row["DepthLevel"] = item.Depth.Level;
row["DepthID"] = item.Depth.ID;
row["DepthCategoryName"] = item.Depth.Category.Name;
row["DepthName"] = item.Depth.Name;
row["DepthCategoryDateUpdated"] = item.Depth.Category.DateUpdated;
row["DepthDateUpdated"] = item.Depth.DateUpdated;
row["Name"] = item.Name;
row["ID"] = item.ID;
row["CategoryCode"] = item.Category.Code;
row["CategoryDateCreated"] = item.Category.DateCreated;
row["CategoryDateUpdated"] = item.Category.DateUpdated;
row["CategoryID"] = item.Category.ID;
row["CategoryName"] = item.Category.Name;
row["Code"] = item.Code;
table.Rows.Add(row);
}
return table;
}
You need to set the table columns to accept nulls.
DataColumn datecolumn = new DataColumn("DateCreated");
datecolumn.AllowDBNull = true;
I would put the Column names in an array and loop through them, ie something similar to this.
DataTable table = new DataTable();
string[] column = { "DateCreated", "DepthCode", "DepthDateCreated" };
foreach (var item in column)
{
DataColumn datecolumn = new DataColumn(item);
datecolumn.AllowDBNull = true;
table.Columns.Add(item);
}

Get N number of columns from datatable c#

I have a datatable where I need to take n number of columns. For ex: From the below datatable I need to take first 10 columns alone with data and put it in another datatable.
Code:
DataTable dtRecord = DAL.GetRecords();
I tried this and this doesn't take the required column.
var selectColumns = dtRecord .Columns.Cast<System.Data.DataColumn>().Take(10);
You can also use this
private DataTable GetNColumnsFromDataTable(DataTable tblSource, int outputCols)
{
DataTable columnOutput = tblSource.Copy();
if (outputCols > 0 && outputCols < tblSource.Columns.Count)
{
while (outputCols < columnOutput.Columns.Count)
{
columnOutput.Columns.RemoveAt(columnOutput.Columns.Count - 1);
}
}
return columnOutput;
}
You can do it like this:
var selectColumns = dtRecord.Columns.Cast<DataColumn>().Take(10);
var dtResult = new DataTable();
foreach (var column in selectColumns)
dtResult.Columns.Add(column.ColumnName);
foreach (DataRow row in dtRecord.Rows)
dtResult.Rows.Add(row.ItemArray.Take(10).ToArray());
Perhaps you should create a column of the same type and with the same expression:
dtResult.Columns.Add(column.ColumnName, column.DataType, column.Expression);
To copy from one DataTable to another, you can extract the columns of interest
var moveCols = dtRecord.Columns.Cast<DataColumn>().Take(10).Select(c => c.ColumnName).ToArray();
Then you must create new DataColumns in a new table, then create new DataRows in the new table:
var newTable = new DataTable();
foreach (var c in moveCols)
newTable.Columns.Add(c);
foreach (var r in dtRecord.AsEnumerable())
newTable.Rows.Add(moveCols.Select(c => r[c]).ToArray());
Which you can make an extension method on DataTable:
public static DataTable Slice(this DataTable dt, params string[] colnames) {
var newTable = new DataTable();
foreach (var c in colnames)
newTable.Columns.Add(c, dt.Columns[c].DataType);
foreach (var r in dt.AsEnumerable())
newTable.Rows.Add(colnames.Select(c => r[c]).ToArray());
return newTable;
}
Now you can call
var newTable = dtRecord.Slice(moveCols);
With a nice extension method, you can convert from Dictionarys to a DataTable dynamically:
var newTable = dtRecord.AsEnumerable().Select(r => moveCols.ToDictionary(c => c, c => r[c])).AsDataTable();
I have some for converting ExpandoObject and anonymous objects as well, as well as an extension to convert those to anonymous objects dynamically. Here is the code for Dictionarys to DataTable:
public static DataTable AsDataTable(this IEnumerable<IDictionary<string, object>> rows) {
var dt = new DataTable();
if (rows.Count() > 0) {
foreach (var kv in rows.First())
dt.Columns.Add(kv.Key, kv.Value.GetType());
foreach (var r in rows)
dt.Rows.Add(r.Values.ToArray());
}
return dt;
}
public static DataTable AsDataTable(this IEnumerable<Dictionary<string, object>> rows) => ((IEnumerable<IDictionary<string, object>>)rows).AsDataTable();
Get 10 columns:
var tbl = new System.Data.DataTable();
var cols = tbl.Columns.Cast<System.Data.DataColumn>().Take(10);
// if you wish to get first 10 columns...
If you want to get the data, then you have to loop through the columns to get the data.
var data = cols.SelectMany(x => tbl.Rows.Cast().Take(10).Select(y => y[x]));
of course, this will dump all the data into an ienumerable, if you want to use strong typed object or a list of one dimensional array, believe it's fairly simple, for example:
var data2 = cols.Select(x => tbl.Rows.Cast().Take(10).Select(y => y[x]).ToArray());

Linq Statement in Datatable

I'm getting the data of my Datatable into a List but i need to get only the items of a matching date how can i do a Linq statement of my datatable to filter the data on the provided date?
My table Structure is taken from a stored procedure
This is my Code:
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("JoinedRecords", conn);
cmd.CommandType = CommandType.StoredProcedure;
conn.Open();
DataTable myTable = new DataTable();
myTable.Load(cmd.ExecuteReader());
conn.Close();
for (var rowIndex = 0; rowIndex < myTable.Rows.Count; rowIndex++)
{
var row = myTable.Rows[rowIndex];
var rowValues = new List<string>();
foreach (DataColumn column in myTable.Columns)//Where column.Date.Day == 3
{
rowValues.Add(row[column].ToString());
}
var jsonRow = JsonConvert.SerializeObject(rowValues);
// Write current row
reader.Write(jsonRow);
// Add separating comma
if (rowIndex != myTable.Rows.Count - 1)
reader.WriteLine(",");
}
How can i do this?
There a data in my datatable that has datetime format
Can you try:
var myTable = new DataTable();
var rowValues = myTable.AsEnumerable().Where(r => r.Field<string>("Date") == "3").ToList();
And use a .Select() before the .ToList() to get what you want?
Hard to provide more with an example of the data you have.
var rowValues = new List<String>();
var value = from r in rowValues
where column.Date.Day == 3
select r;

Categories