[英]How to fill a DataTable with the result of a LINQ?
我有一個調用存儲過程的方法。 它使用員工編號作為參數來檢索特定員工的數據,然后用結果填充數據表。
protected DataTable CreateDT(string empNo)
{
DataTable dataTable = null;
try
{
SqlCommand cmd = new SqlCommand("FIND_EMPLOYEE_BY_EMPNO", pl.ConnOpen());
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@EMPNO", (object)empNo));
SqlDataAdapter da = new SqlDataAdapter(pl.cmd);
dataTable = new DataTable("dt");
da.Fill(dt);
}
catch (Exception x)
{
MessageBox.Show(x.GetBaseException().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
pl.MySQLConn.Close();
}
return dt;
}
我要完成的工作是將此代碼轉換為LINQ,但是我不知道如何獲得結果並將其填充到我的數據表中。 見下文:
替代文字http://a.imageshack.us/img706/9017/testki.jpg
protected DataTable CreateDT(string empNo)
{
DataTable dataTable = null;
try
{
DataClasses1DataContext dataClass1 = new DataClasses1DataContext();
// I tried to cast it to DataTable, but it doesn't work...
dataTable = (DataTable)dataClass1.findEmployeeByID(empNo);
}
catch (Exception x)
{
MessageBox.Show(x.GetBaseException().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
pl.MySQLConn.Close();
}
return dt;
}
請指導我如何正確執行此操作。
為什么需要精確填寫數據表? 大多數使用數據表的可綁定控件都接受標准LINQ的收集結果所產生的任何基於枚舉的對象。
無論如何,您都必須重構代碼以使用LINQ對象,因此您不妨繼續進行所有更改。 從長遠來看,您會更快樂,因為LINQ比ado.net更易於使用。
但是要回答這個問題,您將不得不遍歷列表並將每個元素插入到數據表中。 像這樣(在本文中找到的代碼示例):
public DataTable LINQToDataTable<T>(IEnumerable<T> varlist)
{
DataTable dtReturn = new DataTable();
// column names
PropertyInfo[] oProps = null;
if (varlist == null) return dtReturn;
foreach (T rec in varlist)
{
// Use reflection to get property names, to create table, Only first time, others
will follow
if (oProps == null)
{
oProps = ((Type)rec.GetType()).GetProperties();
foreach (PropertyInfo pi in oProps)
{
Type colType = pi.PropertyType;
if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition()
==typeof(Nullable<>)))
{
colType = colType.GetGenericArguments()[0];
}
dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
}
}
DataRow dr = dtReturn.NewRow();
foreach (PropertyInfo pi in oProps)
{
dr[pi.Name] = pi.GetValue(rec, null) == null ?DBNull.Value :pi.GetValue
(rec,null);
}
dtReturn.Rows.Add(dr);
}
return dtReturn;
}
為什么需要返回一個DataTable
? LINQ的一大優點是您可以使用強類型的集合,而不是字符串鍵的DataTable
。
protected IEnumerable<Employee> GetEmployee(string empNo)
{
try
{
DataClasses1DataContext dataClass1 = new DataClasses1DataContext();
// I tried to cast it to DataTable, but it doesn't work...
return dataClass1.findEmployeeByID(empNo);
}
catch (Exception x)
{
MessageBox.Show(x.GetBaseException().ToString(), "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
finally
{
pl.MySQLConn.Close();
}
}
其他一些要點:
Application.ThreadException
)。 DataContext
類成為一個成員變量,而不是創建和銷毀每個調用。 這樣做的好處是,如果您在同一個實例上執行多個更新,則可以調用一個Save()
並將其全部應用-這導致對服務器的一次調用,而不是對每個服務器的一次調用。 findEmployeeByID
最有可能返回IEnumerable<Employee>
。 考慮到要切換為使用LINQ,實際上應該利用強類型數據並在整個應用程序中使用它們。 因此,更改CreateDT
函數的返回類型並相應地調整其余代碼(我假設存儲過程最多返回一個結果):
protected Employee CreateDT(string empNo)
{
try
{
DataClasses1DataContext dataClass1 = new DataClasses1DataContext();
// I tried to cast it to DataTable, but it doesn't work...
return dataClass1.findEmployeeByID(empNo).FirstOrDefault();
}
catch (Exception x)
{
MessageBox.Show(x.GetBaseException().ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
//might need to dispose the context here
}
return null;
}
用法:
var employee = CreateDT(1234);
//You can now access members of employee in a typesafe manner
string name = employee.Name;
編輯更新的代碼-這是您可以重寫舊的DataTable代碼的方法:
protected void RetrieveEmployee(string empNo) {
Employee emp = CreateDT(empNo);// <---- Here
txtEmployeeNo.Text = emp.EmployeeNo;
txtLastName.Text = emp.LastName;
//....
}
請注意,缺少數組索引和后綁定列說明符-即dt[0]["EmployeeNo"]
變為emp.EmployeeNo
必須更安全,更快emp.EmployeeNo
容易閱讀。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.