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 namedQueryString
. - Public members in C#/.NET should be
PascalCase
notcamelCase
.- So it should be
Section.Title
,Section.Items
,ListItem.Id
,ListItem.Title
, andListItem.Description
.
- So it should be
- 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 anId
,Title
, andDescription
then they should be passed-in as constructor parameters.
- If a
- 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 leastIReadOnlyList<T>
).
- Whereas usually you want something resizable-and-mutable (e.g.
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();