即使关闭验证,我也会在使用Entity Framework将大量数据插入SQL时出现性能问题。
我在网上看到,使用table参数将DataTable插入存储过程非常快,但我不想编写这种类型的代码来安排插入DataTable:
var table = new DataTable();
table.Columns.Add("Id");
table.Columns.Add("Store");
table.Columns.Add("Name");
table.Columns.Add("Amount");
table.Columns.Add("Active");
table.Columns.Add("Status");
foreach (var s in model.Sales)
{
var row = table.NewRow();
row["Id"] = l.Id;
row["Store"] = (int)l.Store;
row["Name"] = l.Name;
row["Amount"] = l.Amount;
row["Active"] = true;
row["Status"] = string.IsNullOrEmpty(l.Status) ? null : l.Status;
table.Rows.Add(row);
}
var parameter = new SqlParameter("Table", SqlDbType.Structured)
{
Value = table,
TypeName = "SqlDefinedTableType"
};
如何从集合中创建DataTable并将其用作SQL表参数?
答案 0 :(得分:2)
您可以使用泛型来解决这些问题。这是一个将类型集合转换为DataTable的方法:
public static DataTable CreateDataTable<T>(ICollection<T> values)
{
var table = new DataTable();
// Get the generic type from the collection
var type = values.GetType().GetGenericArguments()[0];
// Add columns base on the type's properties
foreach (var property in type.GetProperties())
{
/* It is necessary to evaluate whether each property is nullable or not.
* This is because DataTables only support null values in the form of
* DBNull.Value.
*/
var propertyType = property.PropertyType;
var computedType =
// If the type is nullable
propertyType.IsGenericType
&& propertyType.GetGenericTypeDefinition() == typeof(Nullable<>)
// Get its underlying type
? propertyType.GetGenericArguments()[0]
// If it isn't, get return the property type.
: propertyType;
table.Columns.Add(new DataColumn(property.Name, computedType));
}
// Add rows into the DataTable based off of the values
foreach (var value in values)
{
var row = table.NewRow();
foreach (var property in value.GetType().GetProperties())
{
// Create a container to hold the data in the value
object data = null;
// If the property we are adding exists...
if (row.Table.Columns.Contains(property.Name))
// Then get the value of that property
data = value.GetType().GetProperty(property.Name).GetValue(value, null);
// If the value is null, convert the value to DBNull
row[property.Name] = data ?? DBNull.Value;
}
table.Rows.Add(row);
}
return table;
}
然后,您可以使用上述函数返回的DataTable创建SqlParameter
并将其传递给您选择的SqlCommand
。
var parameter = new SqlParameter("Table", SqlDbType.Structured)
{
Value = CreateDataTable(model.Sales),
TypeName = "SqlDefinedTableType"
};
修改:我在原始答案中编辑了该函数以支持可空类型。