Заполните DataTable с помощью LINQ в C #
Вопрос
В моем приложении есть метод, который заполняет DataTable
данными, используя следующий код:
DataTable dt = this.attachmentsDataSet.Tables["Attachments"];
foreach (Outlook.Attachment attachment in this.mailItem.Attachments)
{
DataRow dr = dt.NewRow();
dr["Index"] = attachment.Index;
dr["DisplayName"] = String.Format(
CultureInfo.InvariantCulture,
"{0} ({1})",
attachment.FileName,
FormatSize(attachment.Size));
dr["Name"] = attachment.FileName;
dr["Size"] = attachment.Size;
dt.Rows.Add(dr);
}
Мне было интересно, смогу ли я достичь той же функциональности с помощью LINQ, чтобы немного сократить этот код. Есть идеи?
Решение
Ну, этот код не короче или Linq, но я сделал метод расширения, который берет IList и превращает его в DataTable для вас.
public static DataTable ToDataTable<T>(this IList<T> theList)
{
DataTable theTable = CreateTable<T>();
Type theEntityType = typeof(T);
// Use reflection to get the properties of the generic type (T)
PropertyDescriptorCollection theProperties = TypeDescriptor.GetProperties(theEntityType);
// Loop through each generic item in the list
foreach (T theItem in theList)
{
DataRow theRow = theTable.NewRow();
// Loop through all the properties
foreach (PropertyDescriptor theProperty in theProperties)
{
// Retrieve the value and check to see if it is null
object thePropertyValue = theProperty.GetValue(theItem);
if (null == thePropertyValue)
{
// The value is null, so we need special treatment, because a DataTable does not like null, but is okay with DBNull.Value
theRow[theProperty.Name] = DBNull.Value;
}
else
{
// No problem, just slap the value in
theRow[theProperty.Name] = theProperty.GetValue(theItem);
}
}
theTable.Rows.Add(theRow);
}
return theTable;
}
Другие советы
Да, просто
public void FillFromList(List<T> col)
{
Type elementType = typeof(T);
// Nested query of generic element list of property
// values (using a join to the DataTable columns)
var rows = from row in col
select new
{
Fields = from column in m_dataTable.Columns.Cast<DataColumn>()
join prop in elementType.GetProperties()
on column.Caption equals prop.Name
select prop.GetValue(row, null)
};
// Add each row to the DataTable
int recordCount = 0;
foreach ( var entry in rows )
{
m_dataTable.Rows.Add(entry.Fields.ToArray());
}
Предполагается, что свойства в T такие же, как столбцы DataTable.
Сначала вы определяете, можете ли вы запросить this.mailItem.Attachments
и
если это возможно, вы можете преобразовать результат запроса в набор данных из метода расширения, созданного с помощью Стив Слока ...
Не связан с StackOverflow