get DataTable from Linq Query - c#

I want to get a Datatable from Linq Query, Here is what i done..
public static DataTable GetAllDataNoWise(string UniqueNo)
{
using (var objEntity = new DbContext())
{
var Query = from TBL in objEntity.GenerateCodes.AsEnumerable()
where TBL.UniqueNo == UniqueNo
select new
{
PrimaryID = TBL.GenerateCodeID,
TBL.Code,
ExpiryDate = TBL.ExpiryDate.ToShortDateString(),
};
DataTable dt = LINQToDataTable(Query);
return dt;
}
}
public DataTable LINQToDataTable<T>(IEnumerable<T> varlist)
{
DataTable dtReturn = new DataTable();
PropertyInfo[] oProps = null;
if (varlist == null) return dtReturn;
foreach (T rec in varlist)
{
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;
}
Error is generated like
An object reference is required for the non-static field, method, or property Code.LINQToDataTable<<anonymous type: int PrimaryID, string Code, string ExpiryDate>>(IEnumerable<<anonymous type: int PrimaryID, string Code, string ExpiryDate>>)

Since the first method is static, it can't call your other method unless it is static or instantiated from an object reference.
You can either add static to your second method
public static DataTable LINQToDataTable<T>(IEnumerable<T> varlist)
Or instantiate the class containing your second method and call it from the first method:
var obj = new MyClass();
DataTable dt = obj.LINQToDataTable(Query);

Related

Calling extension method from dynamic list

I am creating a type using reflection...
Type type = Type.GetType("Book");
I am then invoking a method dynamically...
MethodInfo method = typeof(DataHelper).GetMethod("GetTableData");
MethodInfo generic = method.MakeGenericMethod(type);
var parameters = new object[] {...};
dynamic data = generic.Invoke(this, parameters);
The method returns data, and looks like this...
public static IEnumerable<T> GetTableData<T>(parameters)
{
...
}
From the Dynamic data, I want to convert this to a list and call an extension method to convert the List into a DataTable.
I have tried the following, which fails when calling .ToDataTable:
var x = Enumerable.ToList(data);
x.ToDataTable().BulkCopyDataTable(settings, booName);
I have also tried:
var tl = GetTypedList(type);
foreach (var d in x)
{
tl.Add(d);
}
var y = tl.ToDataTable(); // compilaer error.
private static IList GetTypedList(Type t)
{
var listType = typeof(List<>);
var constructedListType = listType.MakeGenericType(t);
var instance = Activator.CreateInstance(constructedListType);
return (IList) instance;
}
The Extension method I am trying to call is:
public static DataTable ToDataTable<T>(this IList<T> data)
{
var properties = TypeDescriptor.GetProperties(typeof(T));
var table = new DataTable();
foreach (PropertyDescriptor prop in properties)
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
foreach (var item in data)
{
var row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
table.Rows.Add(row);
}
return table;
}
Any pointers on where this is going wrong?

SetValue with generic type T

I have this function:
the variable c obtains all the properties of my class <T>
in this case:
c ->
Id
Key
Value
public List<T> ReadStoreProceadure<T>(string storeName)
{
var result = new List<T>();
var instance = (T) Activator.CreateInstance(typeof (T), new object[] {});
var c = typeof (T);
var data = DataReader.ReadStoredProceadures(_factibilidad, storeName); // This part is returning verified data and it's ok
while (data.Read())
{
if (data.HasRows)
{
foreach (var item in c.GetProperties())
{
//item.SetValue(c, item.Name, null);
}
}
}
}
How I can add these values to my instance instance and add it to my result variable?
It's possible?
I've created an extension method for IDataReader that does essentially what I believe you're trying to do:
public static List<T> ToList<T>(this IDataReader dr) where T: new()
{
var col = new List<T>();
var type = typeof(T);
var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
while (dr.Read())
{
var obj = new T();
for (int i = 0; i < dr.FieldCount; i++)
{
string fieldName = dr.GetName(i);
var prop = props.FirstOrDefault(x => x.Name.ToLower() == fieldName.ToLower());
if (prop != null)
{
if (dr[i] != DBNull.Value)
{
prop.SetValue(obj, dr[i], null);
}
}
}
col.Add(obj);
}
dr.Close();
return col;
}
However, you'll notice I've chosen to work the from the other way around. Instead of iterating the type's properties and fetching them from the DataReader, I iterate the DataReader columns and check for a matching property on the type. You should be able to quickly modify this to fit your data retrieval scheme.

Convert DataSet to List

Here is my c# code
Employee objEmp = new Employee();
List<Employee> empList = new List<Employee>();
foreach (DataRow dr in ds.Tables[0].Rows)
{
empList.Add(new Employee { Name = Convert.ToString(dr["Name"]), Age = Convert.ToInt32(dr["Age"]) });
}
It uses a loop to create a List from a dataset.Is there any direct method or shorter method or one line code to convert dataset to list
Try something like this:
var empList = ds.Tables[0].AsEnumerable()
.Select(dataRow => new Employee
{
Name = dataRow.Field<string>("Name")
}).ToList();
Here's extension method to convert DataTable to object list:
public static class Extensions
{
public static List<T> ToList<T>(this DataTable table) where T : new()
{
IList<PropertyInfo> properties = typeof(T).GetProperties().ToList();
List<T> result = new List<T>();
foreach (var row in table.Rows)
{
var item = CreateItemFromRow<T>((DataRow)row, properties);
result.Add(item);
}
return result;
}
private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> properties) where T : new()
{
T item = new T();
foreach (var property in properties)
{
if (property.PropertyType == typeof(System.DayOfWeek))
{
DayOfWeek day = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), row[property.Name].ToString());
property.SetValue(item,day,null);
}
else
{
if(row[property.Name] == DBNull.Value)
property.SetValue(item, null, null);
else
{
if (Nullable.GetUnderlyingType(property.PropertyType) != null)
{
//nullable
object convertedValue = null;
try
{
convertedValue = System.Convert.ChangeType(row[property.Name], Nullable.GetUnderlyingType(property.PropertyType));
}
catch (Exception ex)
{
}
property.SetValue(item, convertedValue, null);
}
else
property.SetValue(item, row[property.Name], null);
}
}
}
return item;
}
}
usage:
List<Employee> lst = ds.Tables[0].ToList<Employee>();
#itay.b
CODE EXPLAINED:
We first read all the property names from the class T using reflection
then we iterate through all the rows in datatable and create new object of T,
then we set the properties of the newly created object using reflection.
The property values are picked from the row's matching column cell.
PS: class property name and table column names must be same
var myData = ds.Tables[0].AsEnumerable().Select(r => new Employee {
Name = r.Field<string>("Name"),
Age = r.Field<int>("Age")
});
var list = myData.ToList(); // For if you really need a List and not IEnumerable
Use the code below:
using Newtonsoft.Json;
string JSONString = string.Empty;
JSONString = JsonConvert.SerializeObject(ds.Tables[0]);
Try this....modify the code as per your needs.
List<Employee> target = dt.AsEnumerable()
.Select(row => new Employee
{
Name = row.Field<string?>(0).GetValueOrDefault(),
Age= row.Field<int>(1)
}).ToList();
DataSet ds = new DataSet();
ds = obj.getXmlData();// get the multiple table in dataset.
Employee objEmp = new Employee ();// create the object of class Employee
List<Employee > empList = new List<Employee >();
int table = Convert.ToInt32(ds.Tables.Count);// count the number of table in dataset
for (int i = 1; i < table; i++)// set the table value in list one by one
{
foreach (DataRow dr in ds.Tables[i].Rows)
{
empList.Add(new Employee { Title1 = Convert.ToString(dr["Title"]), Hosting1 = Convert.ToString(dr["Hosting"]), Startdate1 = Convert.ToString(dr["Startdate"]), ExpDate1 = Convert.ToString(dr["ExpDate"]) });
}
}
dataGridView1.DataSource = empList;
Add a new class named as "Helper" and change the property of the class to "public static"
public static class Helper
{
public static List<T> DataTableToList<T>(this DataTable table) where T : class, new()
{
try
{
List<T> list = new List<T>();
foreach (var row in table.AsEnumerable())
{
T obj = new T();
foreach (var prop in obj.GetType().GetProperties())
{
try
{
PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
propertyInfo.SetValue(obj, Convert.ChangeType(row[prop.Name], propertyInfo.PropertyType), null);
}
catch
{
continue;
}
}
list.Add(obj);
}
return list;
}
catch
{
return null;
}
}
}
and access this class in your code behind as like below
DataTable dtt = dsCallList.Tables[0];
List<CallAssignment> lstCallAssignement = dtt.DataTableToList<CallAssignment>();
Fill the dataset with data from, say a stored proc command
DbDataAdapter adapter = DbProviderFactories.GetFactory(cmd.Connection).CreateDataAdapter();
adapter.SelectCommand = cmd;
DataSet ds = new DataSet();
adapter.Fill(ds);
Get The Schema,
string s = ds.GetXmlSchema();
save it to a file say: datasetSchema.xsd. Generate the C# classes for the Schema: (at the VS Command Prompt)
xsd datasetSchema.xsd /c
Now, when you need to convert the DataSet data to classes you can deserialize (the default name given to the generated root class is NewDataSet):
public static T Create<T>(string xml)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringReader reader = new StringReader(xml))
{
T t = (T)serializer.Deserialize(reader);
reader.Close();
return t;
}
}
var xml = ds.GetXml();
var dataSetObjects = Create<NewDataSet>(xml);
I couldn't get Nitin Sawant's answer to work, but I was able to modify his code to work for me. Essentially I needed to use GetRuntimeFields instead of GetProperties. Here's what I ended up with:
public static class Extensions
{
public static List<T> ToList<T>(this DataTable table) where T : new()
{
IList<FieldInfo> fields = typeof(T).GetRuntimeFields().ToList();
List<T> result = new List<T>();
if (row.Table.Columns.Contains(field.Name))
{
foreach (var row in table.Rows)
{
var item = CreateItemFromRow<T>((DataRow)row, fields);
result.Add(item);
}
}
return result;
}
private static T CreateItemFromRow<T>(DataRow row, IList<FieldInfo> fields) where T : new()
{
T item = new T();
foreach (var field in fields)
{
if (row[field.Name] == DBNull.Value)
field.SetValue(item, null);
else
field.SetValue(item, row[field.Name]);
}
return item;
}
}
Try the above which will run with any list type.
public DataTable ListToDataTable<T>(IList<T> data)
{
PropertyDescriptorCollection props =
TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
for (int i = 0; i < props.Count; i++)
{
PropertyDescriptor prop = props[i];
table.Columns.Add(prop.Name, prop.PropertyType);
}
object[] values = new object[props.Count];
foreach (T item in data)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = props[i].GetValue(item);
}
table.Rows.Add(values);
}
return table;
}
List<GSTEntity.gst_jobwork_to_mfgmaster> ListToGetJwToMfData = new List<GSTEntity.gst_jobwork_to_mfgmaster>();
DataSet getJwtMF = new DataSet();
getJwtMF = objgst_jobwork_to_mfgmaster_BLL.GetDataJobWorkToMfg(AssesseeId, PremiseId, Fyear, MonthId, out webex);
if(getJwtMF.Tables["gst_jobwork_to_mfgmaster"] != null)
{
ListToGetJwToMfData = (from master in getJwtMF.Tables["gst_jobwork_to_mfgmaster"].AsEnumerable() select new GSTEntity.gst_jobwork_to_mfgmaster { Partygstin = master.Field<string>("Partygstin"), Partystate =
master.Field<string>("Partystate"), NatureOfTransaction = master.Field<string>("NatureOfTransaction"), ChallanNo = master.Field<string>("ChallanNo"), ChallanDate=master.Field<int>("ChallanDate"), OtherJW_ChallanNo=master.Field<string>("OtherJW_ChallanNo"), OtherJW_ChallanDate = master.Field<int>("OtherJW_ChallanDate"),
OtherJW_GSTIN=master.Field<string>("OtherJW_GSTIN"),
OtherJW_State = master.Field<string>("OtherJW_State"),
InvoiceNo = master.Field<string>("InvoiceNo"),
InvoiceDate=master.Field<int>("InvoiceDate"),
Description =master.Field<string>("Description"),
UQC= master.Field<string>("UQC"),
qty=master.Field<decimal>("qty"),
TaxValue=master.Field<decimal>("TaxValue"),
Id=master.Field<int>("Id")
}).ToList();

Map RowDataCollection to DTO using AutoMapper

Is there a way to map a RowDataCollection to DTO using AutoMapper?
Here is a scenario: DataRow to Object
user.UserId = row["UserId"];
user.UserName = row["UserName"];
glbal.asax configuration
Mapper.CreateMap<DataRow, EventCompactViewModel>()
.ConvertUsing(x => (EventCompactViewModel)AutomapperExtensions.DataRowMapper(x, typeof(EventCompactViewModel), null));
Data row mapper
public static object DataRowMapper(DataRow dataRow, Type type, string prefix)
{
try
{
var returnObject = Activator.CreateInstance(type);
foreach (var property in type.GetProperties())
{
foreach (DataColumn key in dataRow.Table.Columns)
{
string columnName = key.ColumnName;
if (!String.IsNullOrEmpty(dataRow[columnName].ToString()))
{
if (String.IsNullOrEmpty(prefix) || columnName.Length > prefix.Length)
{
String propertyNameToMatch = String.IsNullOrEmpty(prefix) ? columnName : columnName.Substring(property.Name.IndexOf(prefix) + prefix.Length + 1);
propertyNameToMatch = propertyNameToMatch.ToPascalCase();
if (property.Name == propertyNameToMatch)
{
Type t = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
object safeValue = (dataRow[columnName] == null) ? null : Convert.ChangeType(dataRow[columnName], t);
property.SetValue(returnObject, safeValue, null);
}
}
}
}
}
return returnObject;
}
catch (MissingMethodException)
{
return null;
}
}
You could do a custom type converter. And, if you're sure the DTO property names will exactly match the DataRow column names, you could probably do a little reflection and have a single type converter.

Convert DataTable to IEnumerable<T>

I am trying to convert a DataTable to an IEnumerable. Where T is a custom type I created. I know I can do it by creating a List<T> but I was thinking if there is a slicker way to do it using IEnumerable. Here is what I have now:
private IEnumerable<TankReading> ConvertToTankReadings(DataTable dataTable)
{
var tankReadings = new List<TankReading>();
foreach (DataRow row in dataTable.Rows)
{
var tankReading =
new TankReading
{
TankReadingsID = Convert.ToInt32(row["TRReadingsID"]),
TankID = Convert.ToInt32(row["TankID"]),
ReadingDateTime = Convert.ToDateTime(row["ReadingDateTime"]),
ReadingFeet = Convert.ToInt32(row["ReadingFeet"]),
ReadingInches = Convert.ToInt32(row["ReadingInches"]),
MaterialNumber = row["MaterialNumber"].ToString(),
EnteredBy = row["EnteredBy"].ToString(),
ReadingPounds = Convert.ToDecimal(row["ReadingPounds"]),
MaterialID = Convert.ToInt32(row["MaterialID"]),
Submitted = Convert.ToBoolean(row["Submitted"]),
};
tankReadings.Add(tankReading);
}
return tankReadings.AsEnumerable();
}
The key part being I am creating a List<T> then returning it using AsEnumerable().
There's also a DataSetExtension method called "AsEnumerable()" (in System.Data) that takes a DataTable and returns an Enumerable. See the MSDN doc for more details, but it's basically as easy as:
dataTable.AsEnumerable()
The downside is that it's enumerating DataRow, not your custom class. A "Select()" LINQ call could convert the row data, however:
private IEnumerable<TankReading> ConvertToTankReadings(DataTable dataTable)
{
return dataTable.AsEnumerable().Select(row => new TankReading
{
TankReadingsID = Convert.ToInt32(row["TRReadingsID"]),
TankID = Convert.ToInt32(row["TankID"]),
ReadingDateTime = Convert.ToDateTime(row["ReadingDateTime"]),
ReadingFeet = Convert.ToInt32(row["ReadingFeet"]),
ReadingInches = Convert.ToInt32(row["ReadingInches"]),
MaterialNumber = row["MaterialNumber"].ToString(),
EnteredBy = row["EnteredBy"].ToString(),
ReadingPounds = Convert.ToDecimal(row["ReadingPounds"]),
MaterialID = Convert.ToInt32(row["MaterialID"]),
Submitted = Convert.ToBoolean(row["Submitted"]),
});
}
Nothing wrong with that implementation. You might give the yield keyword a shot, see how you like it:
private IEnumerable<TankReading> ConvertToTankReadings(DataTable dataTable)
{
foreach (DataRow row in dataTable.Rows)
{
yield return new TankReading
{
TankReadingsID = Convert.ToInt32(row["TRReadingsID"]),
TankID = Convert.ToInt32(row["TankID"]),
ReadingDateTime = Convert.ToDateTime(row["ReadingDateTime"]),
ReadingFeet = Convert.ToInt32(row["ReadingFeet"]),
ReadingInches = Convert.ToInt32(row["ReadingInches"]),
MaterialNumber = row["MaterialNumber"].ToString(),
EnteredBy = row["EnteredBy"].ToString(),
ReadingPounds = Convert.ToDecimal(row["ReadingPounds"]),
MaterialID = Convert.ToInt32(row["MaterialID"]),
Submitted = Convert.ToBoolean(row["Submitted"]),
};
}
}
Also the AsEnumerable isn't necessary, as List<T> is already an IEnumerable<T>
Simple method using System.Data.DataSetExtensions:
table.AsEnumerable().Select(row => new TankReading{
TankReadingsID = Convert.ToInt32(row["TRReadingsID"]),
TankID = Convert.ToInt32(row["TankID"]),
ReadingDateTime = Convert.ToDateTime(row["ReadingDateTime"]),
ReadingFeet = Convert.ToInt32(row["ReadingFeet"]),
ReadingInches = Convert.ToInt32(row["ReadingInches"]),
MaterialNumber = row["MaterialNumber"].ToString(),
EnteredBy = row["EnteredBy"].ToString(),
ReadingPounds = Convert.ToDecimal(row["ReadingPounds"]),
MaterialID = Convert.ToInt32(row["MaterialID"]),
Submitted = Convert.ToBoolean(row["Submitted"]),
});
Or:
TankReading TankReadingFromDataRow(DataRow row){
return new TankReading{
TankReadingsID = Convert.ToInt32(row["TRReadingsID"]),
TankID = Convert.ToInt32(row["TankID"]),
ReadingDateTime = Convert.ToDateTime(row["ReadingDateTime"]),
ReadingFeet = Convert.ToInt32(row["ReadingFeet"]),
ReadingInches = Convert.ToInt32(row["ReadingInches"]),
MaterialNumber = row["MaterialNumber"].ToString(),
EnteredBy = row["EnteredBy"].ToString(),
ReadingPounds = Convert.ToDecimal(row["ReadingPounds"]),
MaterialID = Convert.ToInt32(row["MaterialID"]),
Submitted = Convert.ToBoolean(row["Submitted"]),
};
}
// Now you can do this
table.AsEnumerable().Select(row => return TankReadingFromDataRow(row));
Or, better yet, create a TankReading(DataRow r) constructor, then this becomes:
table.AsEnumerable().Select(row => return new TankReading(row));
If you are producing the DataTable from an SQL query, have you considered simply using Dapper instead?
Then, instead of making a SqlCommand with SqlParameters and a DataTable and a DataAdapter and on and on, which you then have to laboriously convert to a class, you just define the class, make the query column names match the field names, and the parameters are bound easily by name. You already have the TankReading class defined, so it will be really simple!
using Dapper;
// Below can be SqlConnection cast to DatabaseConnection, too.
DatabaseConnection connection = // whatever
IEnumerable<TankReading> tankReadings = connection.Query<TankReading>(
"SELECT * from TankReading WHERE Value = #value",
new { value = "tank1" } // note how `value` maps to `#value`
);
return tankReadings;
Now isn't that awesome? Dapper is very optimized and will give you darn near equivalent performance as reading directly with a DataAdapter.
If your class has any logic in it at all or is immutable or has no parameterless constructor, then you probably do need to have a DbTankReading class (as a pure POCO/Plain Old Class Object):
// internal because it should only be used in the data source project and not elsewhere
internal sealed class DbTankReading {
int TankReadingsID { get; set; }
DateTime? ReadingDateTime { get; set; }
int ReadingFeet { get; set; }
int ReadingInches { get; set; }
string MaterialNumber { get; set; }
string EnteredBy { get; set; }
decimal ReadingPounds { get; set; }
int MaterialID { get; set; }
bool Submitted { get; set; }
}
You'd use that like this:
IEnumerable<TankReading> tankReadings = connection
.Query<DbTankReading>(
"SELECT * from TankReading WHERE Value = #value",
new { value = "tank1" } // note how `value` maps to `#value`
)
.Select(tr => new TankReading(
tr.TankReadingsID,
tr.ReadingDateTime,
tr.ReadingFeet,
tr.ReadingInches,
tr.MaterialNumber,
tr.EnteredBy,
tr.ReadingPounds,
tr.MaterialID,
tr.Submitted
});
Despite the mapping work, this is still less painful than the data table method. This also lets you perform some kind of logic, though if the logic is any more than very simple straight-across mapping, I'd put the logic into a separate TankReadingMapper class.
If you want to convert any DataTable to a equivalent IEnumerable vector function.
Please take a look at the following generic function, this may help your needs (you may need to include write cases for different datatypes based on your needs).
/// <summary>
/// Get entities from DataTable
/// </summary>
/// <typeparam name="T">Type of entity</typeparam>
/// <param name="dt">DataTable</param>
/// <returns></returns>
public IEnumerable<T> GetEntities<T>(DataTable dt)
{
if (dt == null)
{
return null;
}
List<T> returnValue = new List<T>();
List<string> typeProperties = new List<string>();
T typeInstance = Activator.CreateInstance<T>();
foreach (DataColumn column in dt.Columns)
{
var prop = typeInstance.GetType().GetProperty(column.ColumnName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
if (prop != null)
{
typeProperties.Add(column.ColumnName);
}
}
foreach (DataRow row in dt.Rows)
{
T entity = Activator.CreateInstance<T>();
foreach (var propertyName in typeProperties)
{
if (row[propertyName] != DBNull.Value)
{
string str = row[propertyName].GetType().FullName;
if (entity.GetType().GetProperty(propertyName).PropertyType == typeof(System.String))
{
object Val = row[propertyName].ToString();
entity.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public).SetValue(entity, Val, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, null, null);
}
else if (entity.GetType().GetProperty(propertyName).PropertyType == typeof(System.Guid))
{
object Val = Guid.Parse(row[propertyName].ToString());
entity.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public).SetValue(entity, Val, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, null, null);
}
else
{
entity.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public).SetValue(entity, row[propertyName], BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, null, null);
}
}
else
{
entity.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public).SetValue(entity, null, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, null, null);
}
}
returnValue.Add(entity);
}
return returnValue.AsEnumerable();
}
Universal extension method for DataTable. May be somebody be interesting. Idea creating dynamic properties I take from another post: https://stackoverflow.com/a/15819760/8105226
public static IEnumerable<dynamic> AsEnumerable(this DataTable dt)
{
List<dynamic> result = new List<dynamic>();
Dictionary<string, object> d;
foreach (DataRow dr in dt.Rows)
{
d = new Dictionary<string, object>();
foreach (DataColumn dc in dt.Columns)
d.Add(dc.ColumnName, dr[dc]);
result.Add(GetDynamicObject(d));
}
return result.AsEnumerable<dynamic>();
}
public static dynamic GetDynamicObject(Dictionary<string, object> properties)
{
return new MyDynObject(properties);
}
public sealed class MyDynObject : DynamicObject
{
private readonly Dictionary<string, object> _properties;
public MyDynObject(Dictionary<string, object> properties)
{
_properties = properties;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return _properties.Keys;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (_properties.ContainsKey(binder.Name))
{
result = _properties[binder.Name];
return true;
}
else
{
result = null;
return false;
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (_properties.ContainsKey(binder.Name))
{
_properties[binder.Name] = value;
return true;
}
else
{
return false;
}
}
}
I wrote an article on this subject over here.
I think it could help you.
Typically it's doing something like that:
static void Main(string[] args)
{
// Convert from a DataTable source to an IEnumerable.
var usersSourceDataTable = CreateMockUserDataTable();
var usersConvertedList = usersSourceDataTable.ToEnumerable<User>();
// Convert from an IEnumerable source to a DataTable.
var usersSourceList = CreateMockUserList();
var usersConvertedDataTable = usersSourceList.ToDataTable<User>();
}
PagedDataSource objPage = new PagedDataSource();
DataView dataView = listData.DefaultView;
objPage.AllowPaging = true;
objPage.DataSource = dataView;
objPage.PageSize = PageSize;
TotalPages = objPage.PageCount;
objPage.CurrentPageIndex = CurrentPage - 1;
//Convert PagedDataSource to DataTable
System.Collections.IEnumerator pagedData = objPage.GetEnumerator();
DataTable filteredData = new DataTable();
bool flagToCopyDTStruct = false;
while (pagedData.MoveNext())
{
DataRowView rowView = (DataRowView)pagedData.Current;
if (!flagToCopyDTStruct)
{
filteredData = rowView.Row.Table.Clone();
flagToCopyDTStruct = true;
}
filteredData.LoadDataRow(rowView.Row.ItemArray, true);
}
//Here is your filtered DataTable
return filterData;

Categories

Resources