Home > database >  Convert DataTable to Array
Convert DataTable to Array

Time:03-11

I convert a DataTable with 10 rows or more into an Array like this:

        SqlConfiguration clist2 = new SqlConfiguration();
        clist2.QueryString = "SELECT caption_id,caption,description FROM sws_template_detail WHERE template_id = 1";

         DataTable db = clist2.GetRecords;

         ListItem datalist = new ListItem();

         foreach(DataRow row in db.Rows)
         {
             datalist = new ListItem
             {
                 id = row["caption_id"].ToString(),
                 title = row["caption"].ToString(),
                 description = row["description"].ToString()
             };
         }

         var section = new Section
         {
             title = "Title",
             items = new ListItem[]
             {
                 datalist
             }
         };

but the resulting data is only 1 row, how to solve it?

CodePudding user response:

You can do it in 1 line (well, 1 statement):

var section = new Section
{
    title = "Title",
    items = dataTable.Rows
        .Cast<DataRow>()
        .Select( row => new ListItem()
        {
            id          = row["caption_id" ].ToString(),
            title       = row["caption"    ].ToString(),
            description = row["description"].ToString()
        } )
        .ToArray()
};

Though there's a lot of code smells going on here...

  • Why is an class named SqlConfiguration being used to execute a SQL query via a property named QueryString.
  • Public members in C#/.NET should be PascalCase not camelCase.
    • So it should be Section.Title, Section.Items, ListItem.Id, ListItem.Title, and ListItem.Description.
  • Don't use object-initializers for required members of an object, because there's no compile-time guarantees that they'll be populated.
    • If a ListItem must have an Id, Title, and Description then they should be passed-in as constructor parameters.
  • Using array-types (like ListItem[]) is usually not a good idea because array-types have the worst set of attributes in comparison to others: they're fixed-size but also mutable.
    • Whereas usually you want something resizable-and-mutable (e.g. List<T>) or completely immutable (e.g. ImmutableArray<T> or at least IReadOnlyList<T>).
Mutable elements Resizable Variance
T[] (Array types ) Yes No Unsafe
List<T> Yes Yes Invariant
ImmutableArray<T> No No Invariant
IReadOnlyList<T> No No Covariant safe

CodePudding user response:

try this

var items_array=new List<ListItem>();
         foreach(DataRow row in db.Rows)
         {
items_array.add(new ListItem
             {
                 id = row["caption_id"].ToString(),
                 title = row["caption"].ToString(),
                 description = row["description"].ToString()
             });
         }

         var section = new Section
         {
             title = "Title",
             items = items_array.toArray()
         };

CodePudding user response:

Loading the data into a DataTable and then converting it into a List wastes both CPU and RAM. You can use an ORM like EF Core or Dapper to execute a query and return the results in the shape you want. For example, using Dapper, what you want is a single line:

var sql=@"select caption_id as Id, caption as Title, description 
FROM sws_template_detail 
WHERE template_id = 1";

var items=connection.Query<ListItem>(sql).ToArray();

Query<T> returns the results as an IEnumerable<T>. This is converted to an array using ToArray().

Dapper allows you to easily write parameterized queries instead of concatenating strings to construct a query:

var sql=@"select caption_id as Id, caption as Title, description 
FROM sws_template_detail 
WHERE template_id = @id";

var items=connection.Query<ListItem>(sql,new {id=1}).ToArray();

The query can be executed asynchronously using QueryAsync;

var items=(await connection.QueryAsync<ListItem>(sql,new {id=1}))
          .ToArray();
  •  Tags:  
  • c#
  • Related