I have following string,
I want to convert it to DataTable
"Id,Name ,Dept\r\n1,Mike,IT\r\n2,Joe,HR\r\n3,Peter,IT\r\n"
I can create it using String.Split and iterating through collection.
But I need efficient way (using C# 4.0 features)
How to create table using LINQ or lambda.
I don't know if that what are you looking for :
string s = "Id,Name ,Dept\r\n1,Mike,IT\r\n2,Joe,HR\r\n3,Peter,IT\r\n";
DataTable dt = new DataTable();
string[] tableData = s.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var col = from cl in tableData[0].Split(",".ToCharArray())
select new DataColumn(cl);
dt.Columns.AddRange(col.ToArray());
(from st in tableData.Skip(1)
select dt.Rows.Add(st.Split(",".ToCharArray()))).ToList();
I Think this method will be useful. This method can be used for both CSVString or CsvFilePath. If you want to convert CsvFilePath then you have to specify first path has true else false.
public DataTable ConvertCsvStringToDataTable(bool isFilePath,string CSVContent)
{
//CSVFilePathName = #"C:\test.csv";
string[] Lines;
if (isFilePath)
{
Lines = File.ReadAllLines(CSVContent);
}
else
{
Lines = CSVContent.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
}
string[] Fields;
Fields = Lines[0].Split(new char[] { ',' });
int Cols = Fields.GetLength(0);
DataTable dt = new DataTable();
//1st row must be column names; force lower case to ensure matching later on.
for (int i = 0; i < Cols; i++)
dt.Columns.Add(Fields[i].ToLower(), typeof(string));
DataRow Row;
for (int i = 1; i < Lines.GetLength(0); i++)
{
Fields = Lines[i].Split(new char[] { ',' });
Row = dt.NewRow();
for (int f = 0; f < Cols; f++)
Row[f] = Fields[f];
dt.Rows.Add(Row);
}
return dt;
}
using System;
using System.Xml;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public static string DataTableToString(DataTable dtData)
{
string sData = null;
StringBuilder sBuffer = null;
string Token = null;
int i = 0;
int j = 0;
sBuffer = new StringBuilder();
sBuffer.Append(#"<TABLE>");
sBuffer.Append(#"<TR>");
foreach (DataColumn Col in dtData.Columns)
{
sBuffer.Append(#"<TH ColType='")
.Append(Convert.ToString(Col.DataType))
.Append(#"'>")
.Append(Col.ColumnName.Replace("&", ""))
.Append(#"</TH>");
}
sBuffer.Append(#"</TR>");
i = 0;
foreach (DataRow rw in dtData.Rows)
{
sBuffer.Append(#"<TR>");
j = 0;
foreach (DataColumn Col in dtData.Columns)
{
if (!Convert.IsDBNull(rw[Col.ColumnName]))
{
Token = Convert.ToString(rw[Col.ColumnName]);
}
else
{
Token = null;
}
sBuffer.Append(#"<TD>").Append(Token).Append(#"</TD>");
j++;
}
sBuffer.Append(#"</TR>");
i++;
}
sBuffer.Append(#"</TABLE>");
sData = sBuffer.ToString();
return sData;
}
public static DataTable StringToDataTable(string sXmlData)
{
DataTable dtData = null;
XmlDocument xmlDoc = null;
XmlNode RootNode = null;
XmlNodeList TRList = null;
XmlNodeList THList = null;
XmlNodeList TDList = null;
int i = 0;
int j = 0;
XmlAttribute DataTypeAttrib = null;
string sDataType = null;
DataColumn Col = null;
Type ColType;
string Token = null;
DataRow newRw = null;
xmlDoc = new XmlDocument();
xmlDoc.LoadXml(sXmlData);
RootNode = xmlDoc.SelectSingleNode("/TABLE");
if (RootNode != null)
{
dtData = new DataTable();
i = 0;
TRList = RootNode.SelectNodes("TR");
foreach (XmlNode TRNode in TRList)
{
if (i == 0)
{
THList = TRNode.SelectNodes("TH");
foreach (XmlNode THNode in THList)
{
DataTypeAttrib = THNode.Attributes["ColType"];
sDataType = DataTypeAttrib.Value;
ColType = Type.GetType(sDataType);
Col = new DataColumn(THNode.InnerText, ColType);
if (!dtData.Columns.Contains(Col.ColumnName))
{
dtData.Columns.Add(Col);
}
}
}
else
{
newRw = dtData.NewRow();
j = 0;
TDList = TRNode.SelectNodes("TD");
foreach (XmlNode TDNode in TDList)
{
ColType = dtData.Columns[j].DataType;
Token = TDNode.InnerText;
if (!string.IsNullOrEmpty(Token))
{
try
{
newRw[j] = Convert.ChangeType(Token, ColType);
}
catch
{
if (ColType == typeof(DateTime))
{
newRw[j] = DateTime.ParseExact(Token, "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
}
}
}
else
{
newRw[j] = Convert.DBNull;
}
j++;
}
dtData.Rows.Add(newRw);
}
i++;
}
}
return dtData;
}
Related
I have a permission form and I want to enter all buttons and MenuStrip to databases.
But when I try to use this function a false message appears
public DataTable loadFormsItemsNameDb(string FormName)
{
var formtype = Assembly.GetExecutingAssembly().GetTypes()
.Where(a => a.BaseType == typeof(Form) && a.GetTypeInfo().Name == FormName)
.FirstOrDefault();
Form f = (Form)Activator.CreateInstance(formtype);
DataTable formsitem = new DataTable();
var ms = f.Controls.OfType<MenuStrip>();
if (ms.Count() > 0)
{
for (int i= 0; i< ms.ElementAt(0).Items.Count; i++)
{
string name = ms.ElementAt(0).Items[i].Name;
string Text = ms.ElementAt(0).Items[i].Text;
string mType = ms.ElementAt(0).Items[i].GetType().ToString();
formsitem.Rows.Add(f.Name, name, Text);
}
}
var BTN = f.Controls.OfType<Button>();
if (BTN.Count() > 0)
{
for (int i = 0; i < BTN.Count(); i++)
{
string name = BTN.ElementAt(i).Name;
string Text = BTN.ElementAt(i).Text;
string mType = BTN.ElementAt(i).GetType().ToString();
formsitem.Rows.Add(f.Name, name, Text, mType);
}
}
return formsitem;
}
After you create a DataTable , you need to define its structure using columns.
for eg.
DataColumn column = new DataColumn();
column.DataType = System.Type.GetType("System.Decimal");
column.AllowDBNull = false;
column.Caption = "Price";
column.ColumnName = "Price";
column.DefaultValue = 25;
table.Columns.Add(column);
and then you can add a row to a table. Here you have not specified the columns for the table.
Form f = (Form)Activator.CreateInstance(formType);
DataTable formsItem = new DataTable();
//************
// Add This Columns Name To Solve Problem ( longer than column )
formsItem.Columns.Add("FIFName");
formsItem.Columns.Add("FIName");
formsItem.Columns.Add("FIText");
formsItem.Columns.Add("FImType");
// *******************
var MS = f.Controls.OfType<MenuStrip>();
Any help would be greatly appreciated. Sorry, if my code is junior. I am new to C#.
Problem
I've dynamically create multiple DataGrids in a flyout, using MahApps. The DataGrids are populated by CSV files (ConvertCSVtoDataTable()). I want the user to be able to make changes to the DataGrids and when they are done, The DataGrids values will replace the CSV files(UpdateDataGridParameter()).
UI Tree: Flyout > StackPanel > GroupBox > DataGrid
Issue
DG.SelectAllCells() does not select from the user changed DataGrid. How can I get the VISUAL UI representation of the DataGid or bind the DT property to a data change event. I hope I explained this correctly. If you have any questions that can help me please post and I will respond quickly. Thanks
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace SpiderRoll.Classes
{
public class DataGridProperties
{
private int IDValue;
public int ID
{
get { return IDValue; }
set { IDValue = value; }
}
private string HeaderValue;
public string Header
{
get { return HeaderValue; }
set { HeaderValue = value; }
}
private string DescriptionValue;
public string Description
{
get { return DescriptionValue; }
set { DescriptionValue = value; }
}
private string NameValue;
public string Name
{
get { return NameValue; }
set { NameValue = value; }
}
private string FilePathValue;
public string FilePath
{
get { return FilePathValue; }
set { FilePathValue = value; }
}
private DataTable DTValue;
public DataTable DT
{
get
{
return DTValue;
}
set
{
DTValue = value;
}
}
public static DataGridProperties DataGridObject(List<DataGridProperties> TBP, int ID = 0, string Name = "")
{
foreach (var tb in TBP)
{
if (tb.ID == ID || tb.Name == Name)
{
return tb;
}
}
return null;
}
public static int FindDataGridID(List<DataGridProperties> DGP, string Name = "")
{
int i = 0;
foreach (var dg in DGP)
{
if (dg.Name == Name)
{
return i;
}
i++;
}
return -1;
}
public static GroupBox DataGridPropertieStackPanel(DataGridProperties DataGrid) // DataGridProperties DataGrid
{
GroupBox GB = new GroupBox();
GB.Header = DataGrid.Header;
StackPanel SPMain = new StackPanel();
SPMain.Orientation = System.Windows.Controls.Orientation.Vertical;
System.Windows.Controls.Label LBDescription = new System.Windows.Controls.Label();
LBDescription.Content = DataGrid.Description;
LBDescription.Margin = new Thickness(10, 0, 0, 0);
SPMain.Children.Add(LBDescription);
StackPanel SP = new StackPanel();
SP.Name = DataGrid.Name;
SP.Orientation = System.Windows.Controls.Orientation.Horizontal;
SP.Margin = new Thickness(10);
System.Windows.Controls.DataGrid DG = new System.Windows.Controls.DataGrid();
DG.Name = DataGrid.Name;
DG.CanUserAddRows = false;
DG.ItemsSource = DataGrid.DT.DefaultView;
SP.Children.Add(DG);
SPMain.Children.Add(SP);
GB.Content = SPMain;
return GB;
}
public static DataTable ConvertCSVtoDataTable(string FilePath)
{
StreamReader sr = new StreamReader(FilePath);
string[] headers = sr.ReadLine().Split(',');
string[] firstLine = sr.ReadLine().Split(',');
DataTable dt = new DataTable();
DataColumn column = new DataColumn();
DataRow fl = dt.NewRow();
int idx = 0;
foreach (string header in headers)
{
//If bool is in first row, turn the column into a checkbox.
if (firstLine[idx].ToLower() == "true" || firstLine[idx].ToLower() == "false")
{
column = dt.Columns.Add(header, typeof(bool));
}
else
{
column = dt.Columns.Add(header, typeof(string));
column.ReadOnly = true;
}
if (header.EndsWith("~"))
{
column.ReadOnly = true;
}
//Reading and building the first row
fl[idx] = firstLine[idx];
idx++;
}
//Adding first row
dt.Rows.Add(fl);
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
string[] rows = line.Split(',');
DataRow dr = dt.NewRow();
for (int i = 0; i < headers.Length; i++)
{
dr[i] = rows[i];
}
dt.Rows.Add(dr);
}
return dt;
}
public static void UpdateDataGridParameter(DataGrid DG)
{
StringBuilder sb = new StringBuilder();
IEnumerable<string> columnNames = DG.Columns.Cast<DataGridColumn>().
Select(column => column.Header.ToString());
sb.AppendLine(string.Join(",", columnNames));
DG.UnselectAllCells();
DG.SelectAllCells();
foreach (DataRowView row in DG.SelectedItems)
{
IEnumerable<string> fields = row.Row.ItemArray.Select(field => field.ToString());
sb.AppendLine(string.Join(",", fields));
}
DG.UnselectAllCells();
var filePath = #"C:\IO\" + DG.Name + ".csv";
File.WriteAllText(filePath, sb.ToString());
}
}
}
In Class Bundle, I create a list of DataGrids
private List<DataGridProperties> dataGridList;
public List<DataGridProperties> DataGridList
{
get
{
return dataGridList;
}
set
{
dataGridList = value;
}
}
In Main, I iterate the DataGridlist and populate StackPanels by calling the DataGridPropertieStackPanel function.
foreach (var item in bundle.DataGridList)
{
if (item.Name == DataGrid.Name)
{
sPanelParameters.Children.Add(DataGridProperties.DataGridPropertieStackPanel(item));
}
}
Your DataGrid updates the binded DataView once you change the values. You don't have to select and unselect the grid rows, just access the dataview directly. Slightly changed version of your code:
public static void UpdateDataGridParameter(DataGrid dataGrid)
{
StringBuilder sb = new StringBuilder();
var dataView = dataGrid.ItemsSource as DataView;
var columnNames = dataView.Table.Columns
.Cast<DataColumn>()
.Select(column => column.ColumnName);
sb.AppendLine(string.Join(",", columnNames));
foreach (DataRowView row in dataView)
{
IEnumerable<string> fields = row.Row.ItemArray.Select(field => field.ToString());
sb.AppendLine(string.Join(",", fields));
}
var filePath = #"C:\IO\" + dataGrid.Name + ".csv";
File.WriteAllText(filePath, sb.ToString());
}
i am making a Job reporter application, and till now what i did is, imported C.S.V file to grid view and displaying it by saving it in a data table, now what i want is,update and save the record back in the c.s.v file, i am not using any S.Q.L or any type of database, is it possible to do this?
please help me, i have to deliver project in two hours.
The project is C# Win forms.
Also help me in how i can serialize it to upload into ftp server.
THE CODE IS here...
private void openProjectToolStripMenuItem_Click_1(object sender, EventArgs e)
{
// int size = -1;
OpenFileDialog ofd = new OpenFileDialog()
{
Title = "Choose a File",
InitialDirectory = #"c:\dev\",
Filter = "Text Files (.txt)|*.txt|XML Files|*.xml|Word Documents (.docx)|*.docx",
RestoreDirectory = true,
Multiselect = false
};
if (ofd.ShowDialog() != System.Windows.Forms.DialogResult.OK)
{
MessageBox.Show("No file selected!");
return;
}
using (StreamReader oStreamReader = new StreamReader(ofd.FileName))
{
try
{
Application.DoEvents();
DataSet ds = new DataSet("ApplicationData");
//some updates in the Datatable
DataTable JobHeaderDataTable = new DataTable("JobHeaderDataTable");
DataTable JobDate = new DataTable("JobDate");
DataTable JobDateItems = new DataTable("JobDateItems");
ds.Tables.Add(JobHeaderDataTable);
ds.Tables.Add(JobDate);
ds.Tables.Add(JobDateItems);
int rowCount = 0;
string[] columnNames = null;
string[] oStreamDataValues = null;
while (!oStreamReader.EndOfStream)
{
string oStreamRowData = oStreamReader.ReadLine().Trim();
if (oStreamRowData.Length > 0)
{
oStreamDataValues = oStreamRowData.Split('-');
if (rowCount == 0 && oStreamDataValues[0].ToString() == "HDR")
{
rowCount = 1;
columnNames = oStreamDataValues;
for (int i = 1; i < columnNames.Length; i++)
{
DataColumn oDataColumn = new DataColumn(columnNames[i].ToUpper(), typeof(string));
oDataColumn.DefaultValue = string.Empty;
JobHeaderDataTable.Columns.Add(oDataColumn);
}
//// For Slider
//txtCompany.Text = oStreamDataValues.GetValue(1).ToString();
//txtLocation.Text = oStreamDataValues.GetValue(2).ToString();
//txtRigName.Text = oStreamDataValues.GetValue(3).ToString();
//txtState.Text = oStreamDataValues.GetValue(4).ToString();
//txtCounty.Text = oStreamDataValues.GetValue(5).ToString();
//txtWellName.Text = oStreamDataValues.GetValue(6).ToString();
//txtTownship.Text = oStreamDataValues.GetValue(7).ToString();
//txtDescription.Text = oStreamDataValues.GetValue(8).ToString();
//txtBentHstSub.Text = oStreamDataValues.GetValue(9).ToString();
//txtBilToBend.Text = oStreamDataValues.GetValue(10).ToString();
//txtPadOD.Text = oStreamDataValues.GetValue(11).ToString();
//txtNBStab.Text = oStreamDataValues.GetValue(11).ToString();
//txtJob_ID.Text = oStreamDataValues.GetValue(12).ToString();
//// For Header
//txtCompanyHeader.Text = oStreamDataValues.GetValue(1).ToString();
//txtLocationHeader.Text = oStreamDataValues.GetValue(2).ToString();
//txtRigNameHeader.Text = oStreamDataValues.GetValue(3).ToString();
//txtStateHeader.Text = oStreamDataValues.GetValue(4).ToString();
//txtCountyHeader.Text = oStreamDataValues.GetValue(5).ToString();
//txtWellNameHeader.Text = oStreamDataValues.GetValue(6).ToString();
//txtTownshipHeader.Text = oStreamDataValues.GetValue(7).ToString();
//txtDescriptionHeader.Text = oStreamDataValues.GetValue(8).ToString();
//txtBentHstSubHeader.Text = oStreamDataValues.GetValue(9).ToString();
//txtBillToBendHeader.Text = oStreamDataValues.GetValue(10).ToString();
//txtPadODHeader.Text = oStreamDataValues.GetValue(11).ToString();
//txtNBStabHeader.Text = oStreamDataValues.GetValue(11).ToString();
//txtJob_IDHeader.Text = oStreamDataValues.GetValue(12).ToString();
}
else
{
DataRow oDataRow = JobHeaderDataTable.NewRow();
for (int i = 1; i < columnNames.Length; i++)
{
oDataRow[columnNames[i]] = oStreamDataValues[i] == null ? string.Empty : oStreamDataValues[i].ToString();
}
JobHeaderDataTable.Rows.Add(oDataRow);
}
}
}
oStreamReader.Close();
oStreamReader.Dispose();
foreach (DataRow dr in JobHeaderDataTable.Rows)
{
dataGridView2.DataSource = JobHeaderDataTable;
dataGridView4.DataSource = JobDate;
dataGridView5.DataSource = JobDateItems;
}
}
catch (IOException)
{
}
}
}
Save yourself some headache and check out, ClosedXML, and create the csv using this answer is available Can I save an EXCEL worksheet as CSV via ClosedXML?.
System.IO.File.WriteAllLines(csvFileName,
worksheet.RowsUsed().Select(row =>
string.Join(";", row.Cells(1, row.LastCellUsed(false).Address.ColumnNumber)
.Select(cell => cell.GetValue<string>()))
));
I convert XML into datatable and now want to convert data table into XML again.
I have database in which four XML's are there and have to change that text xml
public ActionResult getChangeContent(string arg, string content)
{
char[] a = { ':' };
string[] id = arg.Split(a);
decimal tid = Convert.ToDecimal(id[0]);
decimal jid = Convert.ToDecimal(id[1]);
string groupname = id[2];
var gp = (from Trans_Mast in r2ge.Transcription_Master where Trans_Mast.Transcription_Id == tid && Trans_Mast.Entity_Id == jid select Trans_Mast).Distinct();
foreach (var g in gp)
{
DataSet ds = new DataSet();
ds.ReadXml(new XmlTextReader(new StringReader(g.Text_xml)));
DataTable text = ds.Tables[0];
for (int i = 0; i < text.Rows.Count; i++)
{
if (text.Rows[i]["group"].Equals(groupname))
{
text.Rows[i]["Text_Text"] = content;
}
text.AcceptChanges();
}
ConvertDatatableToXML(text);
}
return View();
}
public string ConvertDatatableToXML(DataTable dtTemp)
{
MemoryStream str = new MemoryStream();
dtTemp.WriteXml(str, true);
str.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(str);
string xmlstr;
xmlstr = sr.ReadToEnd();
return (xmlstr);
}
Data set is changed but there is no affect on XML.. any suggestion please..
use this piece of code :
private static string ConvertDataTableToXML(DataTable dtBuildSQL)
{
DataSet dsBuildSQL = new DataSet();
StringBuilder sbSQL;
StringWriter swSQL;
string XMLformat;
sbSQL = new StringBuilder();
swSQL = new StringWriter(sbSQL);
dsBuildSQL.Merge(dtBuildSQL, true, MissingSchemaAction.AddWithKey);
dsBuildSQL.Tables[0].TableName = “Table”;
foreach (DataColumn col in dsBuildSQL.Tables[0].Columns)
{
col.ColumnMapping = MappingType.Attribute;
}
dsBuildSQL.WriteXml(swSQL, XmlWriteMode.WriteSchema);
XMLformat = sbSQL.ToString();
return XMLformat;
}
what would be the best way to compare two data table. i populate two data table reading two different xml and now i need to compare and return the difference in terms of datatable.my compare logic was
private DataTable CompareDataTables(DataTable dtFirst, DataTable dtSecond)
{
int result = 0;
bool flag = false;
DataTable dtNoRows = new DataTable();
dtNoRows.Columns.Add("Result");
DataTable dtDiff = new DataTable();
dtDiff.Columns.Add("Field Name");
dtDiff.Columns.Add("Old Value");
dtDiff.Columns.Add("New Value");
DataRow dr = null;
if (dtFirst.Columns.Count == dtSecond.Columns.Count)
{
for (int i = 0; i <= dtFirst.Columns.Count - 1; i++)
{
try
{
DateTime.Parse(dtFirst.Rows[0][dtFirst.Columns[i].ColumnName.ToString()].ToString().Trim());
flag = true;
}
catch (Exception ex)
{
flag = false;
}
if (!flag)
{
if (dtFirst.Rows[0][dtFirst.Columns[i].ColumnName.ToString()].ToString().Trim().ToUpper() != dtSecond.Rows[0][dtSecond.Columns[i].ColumnName.ToString()].ToString().Trim().ToUpper())
{
dr = dtDiff.NewRow();
dr["Field Name"] = dtFirst.Columns[i].ColumnName.ToString();
dr["Old Value"] = dtFirst.Rows[0][dtFirst.Columns[i].ColumnName.ToString()].ToString().Trim();
dr["New Value"] = dtSecond.Rows[0][dtSecond.Columns[i].ColumnName.ToString()].ToString().Trim();
dtDiff.Rows.Add(dr);
}
}
else
{
result = DateTime.Compare(DateTime.Parse(dtFirst.Rows[0][dtFirst.Columns[i].ColumnName.ToString()].ToString()), DateTime.Parse(dtSecond.Rows[0][dtSecond.Columns[i].ColumnName.ToString()].ToString()));
if (result != 0)
{
dr = dtDiff.NewRow();
dr["Field Name"] = dtFirst.Columns[i].ColumnName.ToString();
dr["Old Value"] = DateTime.Parse(dtFirst.Rows[0][dtFirst.Columns[i].ColumnName.ToString()].ToString().Trim()).ToString("MM/dd/yyyy") + " - " + DateTime.Parse(dtFirst.Rows[0][dtFirst.Columns[i].ColumnName.ToString()].ToString().Trim()).ToString("hh:mm:ss");
dr["New Value"] = DateTime.Parse(dtSecond.Rows[0][dtSecond.Columns[i].ColumnName.ToString()].ToString().Trim()).ToString("MM/dd/yyyy") + " - " + DateTime.Parse(dtSecond.Rows[0][dtSecond.Columns[i].ColumnName.ToString()].ToString().Trim()).ToString("hh:mm:ss");
dtDiff.Rows.Add(dr);
}
flag = false;
}
}
}
return dtDiff;
}
my code is working fine but i need to the is there any best way out. please guide me.
you can use LINQ to comparing tables values(two table must have the same structure)
bool flag = false;
if (dtFirst.Columns.Count == dtSecond.Columns.Count)
{
for (int i = 0; i <= dtFirst.Columns.Count - 1; i++)
{
String colName = dtFirst.Columns[i].ColumnName;
var colDataType = dtFirst.Columns[i].DataType.GetType();
var colValue = dtFirst.Columns[i];
flag = dtSecond.AsEnumerable().Any(T => typeof(T).GetProperty(colName).GetValue(T, typeof(colDataType)) == colValue);
}
}
var qry1 = dtDuplicate.AsEnumerable().Select(a => new { SchoolID = a["SchoolMID"].ToString()});
var qry2 = dsValadateSchoolInfo.Tables[1].AsEnumerable().Select(b => new { SchoolID = ["SchoolMID"].ToString() });
var exceptAB = qry1.Except(qry2);
DataTable dtMisMatch = (from a in dtDuplicate.AsEnumerable()
join ab in exceptAB on a["SchoolMID"].ToString() equals ab.SchoolID
select a).CopyToDataTable();