简体   繁体   中英

In C# web forms, how can I load a List from a dataset using generic types?

I am trying to map content from a dataset into a list, but I want to be able to pass the type into the function. I have the following code already:

public class WorkOrderAttachment : DatabaseObject
{
    [TableData]
    //public List<int> attachment_id { get; set; }
    public int attachment_id { get; set; }
    [TableData]
    //public List<int> wo_id { get; set; }
    public int wo_id { get; set; }

    public WorkOrderAttachment()
    {

    }

. . .

public class DatabaseObject
{
    private string _ConnectionString = "";

. . .

    public static List<T> LoadDataAll<T>(T type, DataSet ds)
    {
        List<T> fillList = new List<T>();
        if (ds.Tables[0].Rows.Count > 0)
        {
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                foreach (var prop in type.GetType().GetProperties())
                {
                    if (prop.GetCustomAttributes(typeof(TableData), false).Length > 0 && ds.Tables[0].Columns.Contains(prop.Name.ToLower()))
                    {
                        if (dr[prop.Name.ToLower()] != DBNull.Value)
                        {
                            prop.SetValue(type, Convert.ChangeType(dr[prop.Name.ToLower()], prop.PropertyType), null);
                        }
                        else
                        {
                            // If we are using a string and the value is null, default to an empty string instead
                            if (prop.PropertyType == typeof(String))
                            {
                                if (dr[prop.Name.ToLower()] == DBNull.Value)
                                {
                                    prop.SetValue(type, "", null);
                                }
                            }
                        }
                    }
                }
                fillList.Add(type);
            }
        }
        return fillList;
    }

. . .

I am using it like this:

return DatabaseObject.LoadDataAll<WorkOrderAttachment>(new WorkOrderAttachment(), ds);

This works, but imagine there are two rows in the table in the dataset. The first time this cycles through, it gets to fullList.Add(type) and puts the data in place as it should. "attachment_id = 1, wo_id = 1000"

However, the next time it cycles through, it sets "attachment_id = 2, wo_id = 1000". Everything looks good, but it is not. When I check the fillList, I find two entries, but they are both the last item "attachment_id = 2, wo_id = 1000" duplicated. The first instance (which I know it getting put in place) is overwritten because of the way it is handled by reference, I guess.

(I do not want to use Entity Framework or other ORM in this scenario, but other options for getting the data out of the data set into a List would be appreciate.)

I want to be able to specify something like this (pseudo-code):

List<WorkOrderAttachment> Attachments = DatabaseResult();

But, I also want it to be generic in such a way that I can put any type into DatabaseResult and get my response as a list already loaded with the data. Any suggestions on how to fix this or implement a better solution are appreciated.

I found the answer within another question at StackOverflow even though my question is different than this one. The answer is the same: In C#, how to instantiate a passed generic type inside a method?

public static List<T> LoadDataAll<T>(DataSet ds) where T : new()
{

. . .

    foreach (DataRow dr in ds.Tables[0].Rows)
    {
        T type = new T();
        foreach (var prop in type.GetType().GetProperties())
        {

. . .

Using the where T : new() syntax, I can create a new type for each row, and that is passed into the fillList that is sent back. My usage of this method is as follows:

return DatabaseObject.LoadDataAll<WorkOrderAttachment>(ds);

The returned result is a WorkOrderAttachment List and I simply pass in the data set.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM