Вот идея: комбинируя LINQ с динамическим, вы можете запрашивать нетипизированные наборы данных, как если бы они были набраны.
Например, предположим, что myDataSet является нетипизированным DataSet.С динамической типизацией и методом расширения AsDynamic () возможно следующее:
var query = from cust in myDataSet.Tables[0].AsDynamic()
where cust.LastName.StartsWith ("A")
orderby cust.LastName, cust.FirstName
select new { cust.ID, cust.LastName, cust.FirstName, cust.BirthDate };
Вот как определить метод расширения AsDynamic.Обратите внимание, как он возвращает IEnumerable of dynamic, что делает его пригодным для запросов LINQ:
public static class Extensions
{
public static IEnumerable<dynamic> AsDynamic (this DataTable dt)
{
foreach (DataRow row in dt.Rows) yield return row.AsDynamic();
}
public static dynamic AsDynamic (this DataRow row)
{
return new DynamicDataRow (row);
}
class DynamicDataRow : DynamicObject
{
DataRow _row;
public DynamicDataRow (DataRow row) { _row = row; }
public override bool TryGetMember (GetMemberBinder binder, out object result)
{
result = _row[binder.Name];
return true;
}
public override bool TrySetMember (SetMemberBinder binder, object value)
{
_row[binder.Name] = value;
return true;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return _row.Table.Columns.Cast<DataColumn>().Select (dc => dc.ColumnName);
}
}
}
Подклассы DynamicObject позволяют использовать преимущества пользовательского связывания, когда вы сами решаете процесс разрешения имен членов.В этом случае мы привязываем права доступа get и set к извлечению или хранению объектов в базовом DataRow.