user584018 user584018 - 2 months ago 14
C# Question

how to exclude some list properties to make data table

In below utility function (list to Data Table), how can I exclude some member of list.

Like, I don't want to send the 2 properties "UniqueKey" & "PointToPointData" to the utility method below,

public class PointDataClone
{
public int DataId { get; set; }
public string UniqueKey { get; set; }
public int Count { get; set; }
public List<PointToPointData> PointToPointData { get; set; }
}


Utility Function,

public static DataTable ToDataTable<T>(this List<T> iList)
{
DataTable dataTable = new DataTable();
PropertyDescriptorCollection propertyDescriptorCollection = TypeDescriptor.GetProperties(typeof(T));
for (int i = 0; i < propertyDescriptorCollection.Count; i++)
{
PropertyDescriptor propertyDescriptor = propertyDescriptorCollection[i];
Type type = propertyDescriptor.PropertyType;

if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
type = Nullable.GetUnderlyingType(type);

dataTable.Columns.Add(propertyDescriptor.Name, type);
}
object[] values = new object[propertyDescriptorCollection.Count];
foreach (T iListItem in iList)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = propertyDescriptorCollection[i].GetValue(iListItem);
}
dataTable.Rows.Add(values);
}
return dataTable;
}

Answer

create an attribute

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class DontShowMe : Attribute
{
}

You can then use the attribute to annotate your class

public class PointDataClone
{
    public int DataId { get; set; }
    [DontShowMe]
    public string UniqueKey { get; set; }
    public int Count { get; set; }
    [DontShowMe]
    public List<PointToPointData> PointToPointData { get; set; }
}

and modify your function to query the attributes. You will need an additional using statement

using System.ComponentModel;

add this line to your loop

if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) type = Nullable.GetUnderlyingType(type);

// test attribute to see if it is shown
if (propertyDescriptor.Attributes.Contains(new DontShowMe())) continue;

dataTable.Columns.Add(propertyDescriptor.Name, type);

You will now have to deal with the fact that your object will have more properties than the datatable has columns. I will leave it to you to manage that little detail.

Hope this helps,

Marc

Comments