如何将 Handsontable 数据转换回 C# class
How to convert Handsontable data back into C# class
我正在使用 ajax post 将我的专栏 headers 和数据从 handsontable 发送回 ashx 处理程序。
$.ajax({
type: 'POST',
url: "Scripts/SaveExcelData.ashx",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({"columns": hot.getColHeader(), "rows": hot.getData()}),
success: function (data) {}
});
目前我正在使用 following 来反序列化请求,但未能成功想出任何将行转换为 DataBaseRow 数组的方法 class objects.
var jsonString = String.Empty;
context.Request.InputStream.Position = 0;
using (var inputStream = new StreamReader(context.Request.InputStream))
{
jsonString = inputStream.ReadToEnd();
var results = JsonConvert.DeserializeObject<dynamic>(jsonString);
var columns = results.columns;
var rows = results.rows;
//use columns here to convert rows into DataBaseRow class
}
列看起来像:{["Col1","Col2","Col3"]}
行看起来像:{[["Val1","Val2","Val3"],["Val1","Val2","Val3"],["Val1","Val2","Val3"]]}
我该怎么做?
更新
与其尝试将动态 class 转换为 DataBaseRow class,我发现我实际上可以手动遍历数组值并将它们写入 DataBaseRow class.[= 的新实例中16=]
using (DBEntities edmx = new DBEntities())
{
foreach (var row in rows)
{
DataBaseRow dbr = new DataBaseRow();
edmx.DataBaseRow.Add(dbr);
dbr.LoadedTime = DateTime.Now;
for (int i = 0; i < row.Count; i++)
{
string colval = row[i].ToString();
string colname = columns[i].ToString();
switch (colname)
{
case "Col1":
dbr.DBCol1 = colval;
break;
case "Col2":
dbr.DBCol2 = colval;
break;
case "Col3":
dbr.DBCol3 = colval;
break;
}
}
}
edmx.SaveChanges();
}
这有效,但速度很慢(请参阅评论了解时间)。有没有 faster/better 方法来处理这些数据? (如果重要的话——我实际上有 14 列在开关中映射)
所以我的问题的技术答案可以在我添加的更新中找到(只是将动态对象引用为数组,不要尝试转换它们)。
但是,似乎 Entity Framework 在处理保存大型数据集方面很差。这可以通过将保存分组为块并为每个块重新创建上下文来加快。
我最终重写了它以将值插入到 DataTable
中,然后使用 SqlBulkCopy
将记录保存到数据库中。
var jsonString = String.Empty;
context.Request.InputStream.Position = 0;
using (var inputStream = new StreamReader(context.Request.InputStream))
{
jsonString = inputStream.ReadToEnd();
var results = JsonConvert.DeserializeObject<dynamic>(jsonString);
var columns = results.columns;
var rows = results.rows;
var dt = new DataTable();
for (int i = 0; i < columns.Count; i++)
{
dt.Columns.Add(columns[i].ToString());
}
foreach (var row in rows)
{
var datarow = dt.NewRow();
for (int i = 0; i < row.Count; i++)
{
datarow[i] = row[i];
}
dt.Rows.Add(datarow);
}
using (var connection = new SqlConnection(ConnectionString))
{
SqlTransaction transaction = null;
connection.Open();
try
{
transaction = connection.BeginTransaction();
using (var sqlBulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, transaction))
{
sqlBulkCopy.DestinationTableName = "TABLENAME";
sqlBulkCopy.BatchSize = 100000;
sqlBulkCopy.BulkCopyTimeout = 0;
foreach (DataColumn col in dt.Columns)
{
sqlBulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
}
sqlBulkCopy.WriteToServer(dt);
}
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
}
}
}
我正在使用 ajax post 将我的专栏 headers 和数据从 handsontable 发送回 ashx 处理程序。
$.ajax({
type: 'POST',
url: "Scripts/SaveExcelData.ashx",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({"columns": hot.getColHeader(), "rows": hot.getData()}),
success: function (data) {}
});
目前我正在使用 following 来反序列化请求,但未能成功想出任何将行转换为 DataBaseRow 数组的方法 class objects.
var jsonString = String.Empty;
context.Request.InputStream.Position = 0;
using (var inputStream = new StreamReader(context.Request.InputStream))
{
jsonString = inputStream.ReadToEnd();
var results = JsonConvert.DeserializeObject<dynamic>(jsonString);
var columns = results.columns;
var rows = results.rows;
//use columns here to convert rows into DataBaseRow class
}
列看起来像:{["Col1","Col2","Col3"]}
行看起来像:{[["Val1","Val2","Val3"],["Val1","Val2","Val3"],["Val1","Val2","Val3"]]}
我该怎么做?
更新
与其尝试将动态 class 转换为 DataBaseRow class,我发现我实际上可以手动遍历数组值并将它们写入 DataBaseRow class.[= 的新实例中16=]
using (DBEntities edmx = new DBEntities())
{
foreach (var row in rows)
{
DataBaseRow dbr = new DataBaseRow();
edmx.DataBaseRow.Add(dbr);
dbr.LoadedTime = DateTime.Now;
for (int i = 0; i < row.Count; i++)
{
string colval = row[i].ToString();
string colname = columns[i].ToString();
switch (colname)
{
case "Col1":
dbr.DBCol1 = colval;
break;
case "Col2":
dbr.DBCol2 = colval;
break;
case "Col3":
dbr.DBCol3 = colval;
break;
}
}
}
edmx.SaveChanges();
}
这有效,但速度很慢(请参阅评论了解时间)。有没有 faster/better 方法来处理这些数据? (如果重要的话——我实际上有 14 列在开关中映射)
所以我的问题的技术答案可以在我添加的更新中找到(只是将动态对象引用为数组,不要尝试转换它们)。
但是,似乎 Entity Framework 在处理保存大型数据集方面很差。这可以通过将保存分组为块并为每个块重新创建上下文来加快。
我最终重写了它以将值插入到 DataTable
中,然后使用 SqlBulkCopy
将记录保存到数据库中。
var jsonString = String.Empty;
context.Request.InputStream.Position = 0;
using (var inputStream = new StreamReader(context.Request.InputStream))
{
jsonString = inputStream.ReadToEnd();
var results = JsonConvert.DeserializeObject<dynamic>(jsonString);
var columns = results.columns;
var rows = results.rows;
var dt = new DataTable();
for (int i = 0; i < columns.Count; i++)
{
dt.Columns.Add(columns[i].ToString());
}
foreach (var row in rows)
{
var datarow = dt.NewRow();
for (int i = 0; i < row.Count; i++)
{
datarow[i] = row[i];
}
dt.Rows.Add(datarow);
}
using (var connection = new SqlConnection(ConnectionString))
{
SqlTransaction transaction = null;
connection.Open();
try
{
transaction = connection.BeginTransaction();
using (var sqlBulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, transaction))
{
sqlBulkCopy.DestinationTableName = "TABLENAME";
sqlBulkCopy.BatchSize = 100000;
sqlBulkCopy.BulkCopyTimeout = 0;
foreach (DataColumn col in dt.Columns)
{
sqlBulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
}
sqlBulkCopy.WriteToServer(dt);
}
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
}
}
}