2

I am developing a WCF restful service to expose data in json format. Currently I am using taking data into a datatbale and then iterating each row and putting into a list and then returning. However I want to skip this iteration and want to directly cast the datatble to a List.

This way I will no longer required to write every column mapping in my service...

Current Code:

[OperationContract]
[WebInvoke
(
    Method = "GET",
    BodyStyle = WebMessageBodyStyle.Bare,
    ResponseFormat = WebMessageFormat.Json,
    UriTemplate = "Id/All"
)
]

DataTable dt = new DataTable();

dt = myData;

List<myCls> lstAllmyCls = new List<myCls>();

foreach (DataRow dr in dt.Rows)
{
    DataContactClass DataContactCls= new DataContactClass();
    DataContactCls.Id = Convert.ToInt32(dr["Id"]);
    DataContactCls.Name = dr["Name"].ToString();
    myCls.Add(DataContactCls);
}

return myCls.ToArray();

Changed Code:

var convertlist = (from dr in dt.AsEnumerable()
                   select new DataContactCls()
                   {
                       Id = Convert.ToInt32(dr["Id"]),
                       Name = dr["Name"].ToString()
                   }).ToList();

But here also I am providing column name which I want to avoid while retirning list data as json.

Can anyone suggest anything more feasible ?

Christos
  • 53,228
  • 8
  • 76
  • 108
user2519971
  • 345
  • 3
  • 12
  • 27

2 Answers2

1

Can you try the below code

private List<T> ConvertToList<T>(DataTable dt)
    {
        var columnNames = dt.Columns.Cast<DataColumn>()
            .Select(c => c.ColumnName)
            .ToList();

        var properties = typeof(T).GetProperties();

        return dt.AsEnumerable().Select(row =>
            {
                var objT = Activator.CreateInstance<T>();

                foreach (var pro in properties)
                {
                    if (columnNames.Contains(pro.Name))
                        pro.SetValue(objT, row[pro.Name]);
                }

                return objT;
            }).ToList();

    }

NOTE: There is always a performance impact when using reflection

Rajesh
  • 7,766
  • 5
  • 22
  • 35
  • Getting: Error 12 No overload for method 'SetValue' takes 2 argument. I think the current code would be more feasible w.r.t performance but any ways will check out both. – user2519971 Dec 18 '13 at 07:09
0

Anyone still looking for answer then I did it this way and it generates JSON data fine.

IService.cs Code:

[OperationContract]
        [WebInvoke(Method = "GET", UriTemplate = "/GetProducts/",
            BodyStyle = WebMessageBodyStyle.WrappedRequest,
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json)]
        List<Dictionary<string, string>> GetProducts();

Service.cs Code:

public List<Dictionary<string, string>> GetProducts()
{
    DataTable dtTable = loadProduct();
    Dictionary<string, string> dic = new Dictionary<string, string>();
    List<Dictionary<string, string>> plist = new List<Dictionary<string, string>>();
                foreach (DataRow dr in dtTable.Rows)
                {

                    dic.Add(dr[0].ToString(), dr[1].ToString());

                }
                 plist.Add(dic);
                return plist;
}
Akshay
  • 1,412
  • 2
  • 17
  • 51