在SQL中,我们执行类似这样的操作来批量插入数据表
SqlBulkCopy copy = new SqlBulkCopy(sqlCon);
copy.DestinationTableName = strDestinationTable;
copy.WriteToServer(dtFrom);
Blockquote
Run Code Online (Sandbox Code Playgroud)
但是在PostgreSQL中如何做这个操作
我需要在mySQL数据库中将一个巨大的CSV文件插入到2个具有1:n关系的表中.
CSV文件每周发送一次,大约1GB,需要附加到现有数据.其中每个表都有一个自动增量主键.
我试过了:
还有什么建议?
让我们说简化这是我的数据结构:
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public List<string> Codes { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我需要从csv插入到这个数据库中:
User (1-n) Code
+---+-----+-----+ +---+---+-----+
|PID|FName|LName| |CID|PID|Code |
+---+-----+-----+ +---+---+-----+
| 1 |Jon | Foo | | 1 | 1 | ed3 |
| 2 |Max | Foo | | 2 | 1 | wst |
| 3 |Paul | Foo | | …Run Code Online (Sandbox Code Playgroud) 我的应用程序运行时需要插入两个表.
让我们说我有表格如下
我的问题是数据量.
我需要向tbl_FirstTable插入超过10,000行,并向tbl_SecondTable插入超过500,000行.
如此冷酷,我使用实体框架如下.
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()));
}
} …Run Code Online (Sandbox Code Playgroud) 当我使用我的xxxContext对象并向表发出几个Add时,那么SaveChanges()实体框架如何将其解析为SQL?它只是循环插入到xxx中,或者如果有数百行,是否足够智能发出批量插入命令?
奖金问题:如果它没有发出批量插入有没有办法强制它,所以我的数据库性能不会被单独的插入杀死?或者批量到临时表然后像Upsert一样合并到原始表?
我最近通过Context.Configuration.AutoDetectChangesEnabled = false在执行批量删除之前禁用自动更改检测(),然后重新启用它并保存更改来调整部分运行速度非常慢的应用程序.
我读了几个不同的消息来源解释说,基本上,每当我调用类似.Add()或.Remove()在DbSet上的方法时,都会DetectChanges()被调用,当我们处理大量实体时,这会变得很昂贵.好.
现在我想提请注意这些文章:
禁用和重新启用的替代方法是始终关闭自动检测更改,并明确调用context.ChangeTracker.DetectChanges或努力使用更改跟踪代理.这两个选项都是高级的,可以轻松地将微小的错误引入您的应用程序,因此请小心使用它们.
除非你真的需要,否则不要关闭自动DetectChanges; 它只会让你痛苦.
也许它就在我的面前,但是假设,例如,我用.SaveChanges()一个总是DetectChanges()先调用的方法包装,我会遇到什么错误,我通常不会这样做?我能看到的所有警告只是模糊地表明,如果不进入现状,就会发生不好的事情.
我有一个带有几个表的小型SQL CE 4.0数据库,使用Entity Framework 4进行映射.
这是我的代码
foreach (String designation in newItemDesignations)
{
ParameterData defaultValue = PDM.GetDefaultParameterData(designation);
// Fill the ItemParameterDBO object with the data
ItemParameterDBO dbParam = new ItemParameterDBO();
dbParam.ItemID = dbItem.ID;
dbParam.Designation = designation;
dbParam.High = defaultValue.High;
dbParam.Low = defaultValue.Low;
database.ItemParameterDBOes.AddObject(dbParam);
}
database.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
24 times每次newItemDesignations列表包含时,都会发生此代码exactly 525 elements.这总共需要12600行.
整个过程持续509 seconds.我猜这对12600行来说太多了.
我知道我在打电话SaveChanges 24 times.目前,应用程序设计不允许我将所有插入放入单个事务(with SaveChanges).但是,看看单个事务会发生什么.509 / 24 = 21 seconds或者a 40 ms per row. …
假设一个具有多个并发生成器的系统,每个生成器都努力使用以下可通过其名称唯一标识的公共实体来持久保存一些对象图:
CREATE TABLE CommonEntityGroup(
Id INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
Name NVARCHAR(100) NOT NULL
);
GO
CREATE UNIQUE INDEX IX_CommonEntityGroup_Name
ON CommonEntityGroup(Name)
GO
CREATE TABLE CommonEntity(
Id INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
Name NVARCHAR(100) NOT NULL,
CommonEntityGroupId INT NOT NULL,
CONSTRAINT FK_CommonEntity_CommonEntityGroup FOREIGN KEY(CommonEntityGroupId)
REFERENCES CommonEntityGroup(Id)
);
GO
CREATE UNIQUE INDEX IX_CommonEntity_CommonEntityGroupId_Name
ON CommonEntity(CommonEntityGroupId, Name)
GO
Run Code Online (Sandbox Code Playgroud)
例如,生产者A保存了一些CommonEntityMeetings,而生产者B保存了CommonEntitySets.他们中的任何一个都必须坚持CommonEntity与他们的特定物品相关.
基本上,关键点是:
c# sql-server entity-framework optimistic-concurrency sql-insert
我一直得到如下图所示的结果.我想知道我能做些什么来提高可预测性.我没有使用SqlBulkCopy,因为我需要利用EFv5的验证功能.
如果有人可以验证/反驳我的发现,那就太棒了.我的目标是摆脱两种尖峰.我正在提供以下源代码,以便您快速完成.您只需要一个VS中的类库项目,引用EFv5和NUnit,两者都可以通过NuGet获得.只需将此代码粘贴到Class1中,修改连接字符串并运行它即可.您可以使用下面的sql脚本重新创建表.
我正在使用.Net 4.5,EF 5,NUnit 2.6.1,在发布模式下运行代码,没有附加调试器.db是SqlServer 2008 R2.我使用64位模式的NUnit.exe运行测试,显示"Net 4.0"作为框架版本.

X轴是批号(总共1000批),Y轴是毫秒.您可以看到第一批需要大约30秒,这是因为dbContext是"冷"的.每批保存100个实体.
请注意,这个问题正在寻找这个答案中缺少的一些信息,它是EF保存中的抖动.
这是我正在使用的代码:
桌子:
CREATE TABLE [dbo].[Entity1](
[Id] [int] IDENTITY(1,1) NOT NULL,
[IntField] [int] NOT NULL,
[StrField] [nvarchar](50) NOT NULL,
[DateField] [datetimeoffset](7) NOT NULL,
CONSTRAINT [PK_Entity1] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
课程:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Diagnostics;
using NUnit.Framework;
namespace …Run Code Online (Sandbox Code Playgroud) 我试图Add()大约18000个对象到我的DBContext.花了大约5分钟.使用SaveChanges()保存此数据的时间更长.我切换到创建一个普通的List并将我的对象添加到它,然后我使用SqlBulkCopy来保存数据.这花了大约5秒钟.
Add方法做了什么,这需要花费这么长时间?
我必须像1M实体一样处理以构建事实.应该有大约相同数量的结果事实(100万).
我遇到的第一个问题是批量插入,实体框架很慢.所以我在实体框架中使用了这种最快的插入方式(来自SLauma的回答).我可以在一分钟内快速插入实体,大约100K.
我遇到的另一个问题是缺乏处理所有内容的内存.所以我已经"分页"了处理过程.为了避免内存不足,如果我从我的100万结果事实中列出一个列表,我会得到.
我的问题是即使使用分页,内存也总是在增长,我不明白为什么.每批后没有释放内存.我认为这很奇怪,因为我在循环的每次迭代中获取重建构建事实并将它们存储到DB中.一旦循环完成,那些应该从内存中释放出来.但它看起来并不是因为每次迭代后都没有释放内存.
在我挖掘更多之前,你能否告诉我你是否看错了什么?更具体地说,为什么在迭代循环之后没有释放内存.
static void Main(string[] args)
{
ReceiptsItemCodeAnalysisContext db = new ReceiptsItemCodeAnalysisContext();
var recon = db.Recons
.Where(r => r.Transacs.Where(t => t.ItemCodeDetails.Count > 0).Count() > 0)
.OrderBy( r => r.ReconNum);
// used for "paging" the processing
var processed = 0;
var total = recon.Count();
var batchSize = 1000; //100000;
var batch = 1;
var skip = 0;
var doBatch = true;
while (doBatch)
{ // list to store facts processed during the batch
List<ReconFact> …Run Code Online (Sandbox Code Playgroud) c# ×9
insert ×2
sql-server ×2
.net ×1
ado.net ×1
asp.net-mvc ×1
database ×1
datatable ×1
mysql ×1
performance ×1
postgresql ×1
sql-insert ×1