2

I have a strongly typed class PersonExport. I initially get data into a DataTable and call the following method on the DataTable to convert it to List<PersonExport>:

public static List<T> ConvertToList<T>(DataTable dt, out string message)
    {
        message = string.Empty;
        var list = new List<T>();


        try
        {
            var columnNames = dt.Columns.Cast<DataColumn>()
            .Select(c => c.ColumnName)
            .ToList();

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

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

                foreach (var pro in properties)
                {
                    if (columnNames.Contains(pro.Name))
                    {
                        var value = row[pro.Name];
                        var typeName = value.GetType().FullName;

                        if (typeName == "MySql.Data.Types.MySqlDateTime")
                        {

                            var mySqlDateTime = (MySqlDateTime) value;
                            if (mySqlDateTime.IsValidDateTime)
                            {
                                value = Convert.ToDateTime(mySqlDateTime.ToString());
                                pro.SetValue(objT, value, null);
                            }
                        }
                        else
                        {
                            pro.SetValue(objT, row.IsNull(pro.Name) ? null : value, null);
                        }
                    }
                }

                return objT;
            }).ToList();

        }
        catch (Exception ex)
        {
            message = (ex.InnerException != null) ? ex.InnerException.Message : ex.Message;
        }

        return list;
    }

However, once I start removing columns from the DataTable returned, it no longer works because the columns in the DataTable don't match up with the properties in the PersonExport list.

I am eventually using the exported list here to export to excel, but it is not working since I have modified by DataTable and it can't Deserialize into a List<PersonExport>:

//Trying to get data into List<object>
List<object> persons = GetPersonExport(query, out message);
var exportData = new Dictionary<string, List<object>> { { "xldata", persons} };

//Deserialize to List<object> to export
var persons = JsonConvert.DeserializeObject<List<object>>(args["xldata"]);

The above line just returns a List of empty objects.

A few things got me thinking, but I am wondering what might be the best approach. I am using the EPPLUS library to export data to excel and it has the option of hiding columns, so would it be better to just export the whole object and hide columns you don't want, this way you avoid the anonymous type or what I can do is still get the whole object, but then convert it to a DataTable and then remove the columns? Thoughts?


How to add class for only the selected link in C# code behind?

I have a class called "is-active" and it has a colored arrow that sticks out from the nav into the main content based on which link the user clicked. The code runs a foreach and pulls all the categories from the database. How do I get the "is-active" class to display only for the current link? I know it works since I put it in the openList control and it displayed on all five categories, I just don't know how to get it to display on only the selected category.

I tried attaching jQuery to do it but adding the linkbutton is done all in the code behind so I am not sure how to attach the two. Is this the only way or is there another way?

Thank you in advance for your help!

Below is my code for the categories and link button:

protected override void CreateChildControls()
{
    LiteralControl openingDiv = new LiteralControl("<div id='MainPanel'>");
    LiteralControl closingDiv = new LiteralControl("</div>");   

    this.Controls.Add(openingDiv);

    foreach (DataRow dr in ds.Tables[0].Rows)
    {
        LiteralControl openList = new LiteralControl("<li class='" + dr["CategoryColor"].ToString() + "'>");
        LiteralControl closeList = new LiteralControl("</li>");                

        Label lblNumber = new Label();

        LinkButton myLinkButton = new LinkButton();

        myLinkButton.Text = "<span class='number'>" + dr["CategoryNumber"] + "</span>"+ dr["CategoryName"].ToString();
        myLinkButton.CommandArgument = dr["Category_ID"].ToString();
        myLinkButton.Click += myLinkButton_Click;

        this.Controls.Add(openList);
        this.Controls.Add(myLinkButton);
        this.Controls.Add(closeList);
    }
    this.Controls.Add(closingDiv);
}
void myLinkButton_Click(object sender, EventArgs e)
{
    LinkButton btn = (LinkButton)(sender);
    Session["CategoryID"] = btn.CommandArgument;

    Response.Redirect(Request.RawUrl);  
}
4

2 に答える 2

2

必要なのは次のとおりです。

public IEnumerable<object> GetListOfObject()
{
    foreach (var prod in TenMostExpensiveProducts().Tables[0].AsEnumerable())
    {
        yield return prod;
    }
}

または:

TenMostExpensiveProducts().Tables[0].AsEnumerable().Select (x => x).ToList<object>()

ただし、次のように linq を介してよりエレガントに動作させることができます。

from prod in TenMostExpensiveProducts().Tables[0].AsEnumerable()
where prod.Field<decimal>("UnitPrice") > 62.500M
select prod

またはこのように (AsDynamic は DataSet で直接呼び出されます):

TenMostExpensiveProducts().AsDynamic().Where (x => x.UnitPrice > 62.500M)

私は最後のアプローチを好みますが、これが最も柔軟です。System.Data.DataSetExtensions.dllPS:参照を接続することを忘れないでください

于 2013-11-03T17:42:16.553 に答える
0
      List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
        Dictionary<string, object> row;
        foreach (DataRow dr in dt.Rows)
        {
            row = new Dictionary<string, object>();
            foreach (DataColumn col in dt.Columns)
            {
                row.Add(col.ColumnName, dr[col]);
            }
            rows.Add(row);
        }
        StringBuilder sbRes = new StringBuilder();
        jSon.Serialize(rows, sbRes);
        ret = sbRes.ToString();
于 2014-05-20T17:24:53.057 に答える