cmd.AddTableParam - lobodava/artisan-orm GitHub Wiki
cmd.AddTableParam
is SqlCommand extension method which:
- takes
IEnumarable<T>
collection as parameter, - creates ADO.NET DataTable,
- populates the DataTable with data from the collection,
- creates SqlParemeter with SqlDbType.Structured type,
- add this parameter to the calling command.
To ensure that a stored procedure is able to get the data from table valued parameter, your database MUST have a corresponding user-defined table type created in advance.
Moreover, the DataTable
which is added as SqlDbType.Structured
type parameter MUST have the same name as the user-defined table type in the database.
Even more! The quantity, names and types of columns in the DataTable
MUST correspond to that in the user-defined table type.
So to add table parameter it is required to provide that information.
One way is to use Mappers and their CreateDataTable
and CreateDataRow
methods.
For example, if a Mapper with CreateDataTable
and CreateDataRow
methods exist for a class User
, then cmd.AddTableParam
for the IEnumerable<User>
is:
public void SaveUsers(IList<User> users)
{
return ExecuteCommand(cmd =>
{
cmd.UseProcedure("dbo.SaveUsers");
cmd.AddTableParam("@Users", users);
}
}
Another way is to use auto-mapping which:
- uses the reflection and gets information about column types and values from object PropertyInfo,
- builds the expression trees,
- compiles them to
CreateDataTable
andCreateDataRow
Func
delegates, - caches the
Func
delegates to dictionary with a composite string key, - the composite string key consists of three parts: full type name, table name and concatenated column names.
Thus every next call of auto-mapping function uses cached Func
delegates and the performance is almost the same as the use of the handwritten mappers.
Although the auto-mapping does the magic, it is still required to provide name for DataTable and a list of columns to create. And the names of columns MUST correspond to the existing object properties.
Here is an overload for cmd.AddTableParam
method which uses auto-mapping:
public static void AddTableParam<T>(
this SqlCommand cmd , // calling command
string parameterName , // stored procedure parameter name with leading at sign - @
IEnumerable<T> list , // list of T objects
string tableName , // name of DataTable and corresponding user-defined table type
string columnNames ) // comma separated list with column and corresponding properties names
Use example:
public void SaveUsers(IList<User> users)
{
return ExecuteCommand(cmd =>
{
cmd.UseProcedure("dbo.SaveUsers");
cmd.AddTableParam("@Users", users, "UserTableType", "Id, Login, Name, Email");
}
}
If to omit the list of column names, then the columns will be created based on the found public, non static, simple properties, which has get
method.
See also: