- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有两个表需要在我的应用程序运行时插入。
假设我有如下表格
我的问题是数据量。
我需要向 tbl_FirstTable 插入超过 10,000 行,向 tbl_SecondTable 插入超过 500,000 行。
首先,我使用 Entity Framework 如下。
public bool Save_tbl_FirstTable_Vs_tbl_SecondTable(List<tbl_FirstTable> List_tbl_FirstTable, List<tbl_SecondTable> List_tbl_SecondTable)
{
bool IsSuccessSave = false;
try
{
using (DummyDBClass_ObjectContext _DummyDBClass_ObjectContext = new DummyDBClass_ObjectContext())
{
foreach (tbl_FirstTable _tbl_FirstTable in List_tbl_FirstTable)
{
_DummyDBClass_ObjectContext.tbl_FirstTable.InsertOnSubmit(_tbl_FirstTable);
}
foreach (tbl_SecondTable _tbl_SecondTable in List_tbl_SecondTable)
{
_DummyDBClass_ObjectContext.tbl_SecondTable.InsertOnSubmit(_tbl_SecondTable);
}
_DummyDBClass_ObjectContext.SubmitChanges();
IsSuccessSave = true;
}
}
catch (Exception ex)
{
Log4NetWrapper.WriteError(string.Format("{0} : {1} : Exception={2}",
this.GetType().FullName,
(new StackTrace(new StackFrame(0))).GetFrame(0).GetMethod().Name.ToString(),
ex.Message.ToString()));
if (ex.InnerException != null)
{
Log4NetWrapper.WriteError(string.Format("{0} : {1} : InnerException Exception={2}",
this.GetType().FullName,
(new StackTrace(new StackFrame(0))).GetFrame(0).GetMethod().Name.ToString(),
ex.InnerException.Message.ToString()));
}
}
return IsSuccessSave;
}
那是我遇到错误超时异常
的地方。
我认为如果我使用以下代码,该异常将得到解决。
DummyDBClass_ObjectContext.CommandTimeout = 1800; // 30 minutes
所以我用了它。它解决了,但我遇到了另一个错误 OutOfMemory Exception
。
所以我搜索了解决方案,幸运的是,我找到了以下文章。
根据那些文章,我将我的代码从 Entity Framework 更改为经典 ADO.net 代码。
public bool Save_tbl_FirstTable_Vs_tbl_SecondTable(DataTable DT_tbl_FirstTable, DataTable DT_tbl_SecondTable)
{
bool IsSuccessSave = false;
SqlTransaction transaction = null;
try
{
using (DummyDBClass_ObjectContext _DummyDBClass_ObjectContext = new DummyDBClass_ObjectContext())
{
var connectionString = ((EntityConnection)_DummyDBClass_ObjectContext.Connection).StoreConnection.ConnectionString;
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (transaction = connection.BeginTransaction())
{
using (SqlBulkCopy bulkCopy_tbl_FirstTable = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, transaction))
{
bulkCopy_tbl_FirstTable.BatchSize = 5000;
bulkCopy_tbl_FirstTable.DestinationTableName = "dbo.tbl_FirstTable";
bulkCopy_tbl_FirstTable.ColumnMappings.Add("ID", "ID");
bulkCopy_tbl_FirstTable.ColumnMappings.Add("UploadFileID", "UploadFileID");
bulkCopy_tbl_FirstTable.ColumnMappings.Add("Active", "Active");
bulkCopy_tbl_FirstTable.ColumnMappings.Add("CreatedUserID", "CreatedUserID");
bulkCopy_tbl_FirstTable.ColumnMappings.Add("CreatedDate", "CreatedDate");
bulkCopy_tbl_FirstTable.ColumnMappings.Add("UpdatedUserID", "UpdatedUserID");
bulkCopy_tbl_FirstTable.ColumnMappings.Add("UpdatedDate", "UpdatedDate");
bulkCopy_tbl_FirstTable.WriteToServer(DT_tbl_FirstTable);
}
using (SqlBulkCopy bulkCopy_tbl_SecondTable = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, transaction))
{
bulkCopy_tbl_SecondTable.BatchSize = 5000;
bulkCopy_tbl_SecondTable.DestinationTableName = "dbo.tbl_SecondTable";
bulkCopy_tbl_SecondTable.ColumnMappings.Add("ID", "ID");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("UploadFileDetailID", "UploadFileDetailID");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("CompaignFieldMasterID", "CompaignFieldMasterID");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("Value", "Value");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("Active", "Active");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("CreatedUserID", "CreatedUserID");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("CreatedDate", "CreatedDate");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("UpdatedUserID", "UpdatedUserID");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("UpdatedDate", "UpdatedDate");
bulkCopy_tbl_SecondTable.WriteToServer(DT_tbl_SecondTable);
}
transaction.Commit();
IsSuccessSave = true;
}
connection.Close();
}
}
}
catch (Exception ex)
{
if (transaction != null)
transaction.Rollback();
Log4NetWrapper.WriteError(string.Format("{0} : {1} : Exception={2}",
this.GetType().FullName,
(new StackTrace(new StackFrame(0))).GetFrame(0).GetMethod().Name.ToString(),
ex.Message.ToString()));
if (ex.InnerException != null)
{
Log4NetWrapper.WriteError(string.Format("{0} : {1} : InnerException Exception={2}",
this.GetType().FullName,
(new StackTrace(new StackFrame(0))).GetFrame(0).GetMethod().Name.ToString(),
ex.InnerException.Message.ToString()));
}
}
return IsSuccessSave;
}
最后,它在不到 15 秒的时间内完成了超过 500,000 行的插入过程。
我发布这个场景有两个原因。
因此,我们将不胜感激每一个更好的解决方案。
最佳答案
1)使用EF6.x,性能比EF5.x好很多
这里有更多建议(来自Bulk insert with EF)
2) 通过为每个工作单元使用新上下文来保持事件上下文图较小
3) 关闭 AutoDetechChangesEnabled - context.Configuration.AutoDetectChangesEnabled = false;
4) 批处理,在你的循环中,定期调用 SaveChanges
关于c# - SqlBulkCopy 多个表在单个事务下插入或 Entity Framework 和经典 Ado.net 之间的批量插入操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15471177/
在 .Net Aspx 页面或 Web 服务需要在表中执行大约 20-200 行插入的情况下,您会推荐以下哪种方法?为什么?小的性能提升可能意味着我仍然会使用我最熟悉的方法,所以请告诉我它是否不会产生
SqlBulkCopy可以创建一个类似于SELECT INTO的表吗? 最佳答案 我认为上述答案不太清楚。 您必须使用SQL创建表。没有别的办法了。而且,如果您只需要创建列结构,那么如果您的源代码位于
在我的程序中,我正在填充数据表,然后将其批量复制到我的数据库中。 但是,如果行中的 3 列匹配,我希望它覆盖数据库中的一行。 例如,如果我有 5 列 成员(member)编号注册日期姓名地址城市状态
我熟悉 C# SqlBulkCopy 类,您可以在其中调用通过 DataTable 传递的“WriteToServer”方法。 我的问题是 SQL Server 中使用什么底层机制来批量插入该数据?
SqlBulkCopy 的建议批量大小是多少?我正在寻找一个可以用作性能调整起点的通用公式。 最佳答案 我有一个导入实用程序与我的 SQL Server 实例位于同一物理服务器上。它使用自定义的 ID
这是 TABLE1 的架构: CREATE TABLE [dbo].[TABLE1] ( [id] [int] IDENTITY(1, 1) NOT NULL, [code] [int
要将数据从一个数据库复制到具有相同架构的不同服务器中的另一个数据库,我计划使用 C sharp 库中的 SqlBulkCopy 类。 SqlBulkCopy 在插入记录时是否会保持与数据表中相同的顺序
我可以忽略我传递给 SqlBulkCopy 的数据表中已存在于 sql 数据库中的数据的重复记录吗?如果是,那么如何,如果否和其他选项,还要解释我。 最佳答案 不,这不是内置的。您需要先清理客户端上的
我正在执行从 excel 电子表格到临时表的数据的 sql 批量复制,然后从临时表到生产数据库。 我的问题是,如果由于任何原因上传到临时表或生产数据库失败,事务是否回滚并且没有数据被导入或修改现有数据
我的软件可以部署在两种不同的配置中:一种是我全天偶尔收到单个数据点的涓流馈送,另一种是我在一天结束时得到所有数据的转储。对于日终转储,显然,我将使用具有可配置批处理大小的 SqlBulkCopy()
在我的网络应用程序中,用户可以一次插入大量数据,以提高性能,我正在使用 SqlBulkCopy 类。对于插入两个不同表的单个操作,它会运行多次。如果用户取消操作或操作失败,那么我需要回滚数据,因此我使
我有以下代码..它实际上使用 SQLBulkCopy 将数据插入目标。由于死锁,此代码在源 SQL 服务器中经常失败。仅供引用,正在复制的表可以在我们执行批量复制时使用(我的意思是一些插入/选择将运行
我正在尝试使用 SqlBulkCopy 通过在我的应用程序中手动填充 DataTable 来将新行插入到我的数据库表中。 这适用于所有表除了具有由 3 列组成的复合主键的表。每当我尝试将任何内容 Sq
我正在使用 SqlBulkCopy 将一批记录从 MySQL 复制到 SQL Server。 正好 30 秒后,我明白了 System.Data.SqlClient.SqlException (0x8
这是我的场景:我必须在表中导入大文件,所以我使用了 sqlBulkCopy,因为其他方法太慢了。 这是一个文件行的例子: String1|String2|String3|String4 这是表结构:
有人可以帮我解决这个错误吗?这是我的代码: using System; using System.Drawing; using System.Collections; using System.Com
我正在努力将数据库从 MS Access 迁移到 sql server。为了将数据移动到新表中,我决定编写一个同步例程,因为模式已经发生了相当大的变化,它让我可以在运行它的程序上运行测试,并在我需要新
我正在使用 SqlBulkCopy 对象将生成的几百万行插入到数据库中。唯一的问题是我要插入的表有一个标识列。我尝试将 SqlBulkCopyOptions 设置为 SqlBulkCopyOption
从 csv 文件插入数据。如何使用存储过程而不是 SqlBulkCopy 从数据表插入到数据库?当前使用: using (SqlBulkCopy sqlBulkCopy = new SqlBulkC
我正在尝试找到一种使用 SqlBulkCopy 向 MSSQLServer 表执行批量插入的方法,该方法将在出现错误时继续,并返回无法插入的任何行的数据表。 当我尝试使用 SqlBulkCopy 时,
我是一名优秀的程序员,十分优秀!