C# 使用EF进行高性能插入和复制控制
我了解SQL的基础知识,因此我学会了创建插入查询,如以下查询:C# 使用EF进行高性能插入和复制控制,c#,asp.net,sql-server,entity-framework,C#,Asp.net,Sql Server,Entity Framework,我了解SQL的基础知识,因此我学会了创建插入查询,如以下查询: queryAccount.AppendLine( string.Format( "Insert INTO Account(Number_Account, DoID, ClientID) Select " + "{0}, " + "(Select id From AccountDO Where Number_do = {1}), " + "
queryAccount.AppendLine(
string.Format(
"Insert INTO Account(Number_Account, DoID, ClientID) Select "
+ "{0}, "
+ "(Select id From AccountDO Where Number_do = {1}), "
+ "(Select id From Client Where Number_Client = {2})"
+ "Where not exists(Select * From Account Where Number_Account = {0});",
item.Client.NumberAccount,
item.Client.NumberDo,
item.Client.NumberClient));
在该查询中,我将数据添加到具有两个FK(DoID
和ClientID
)的表“Account”,并检查该帐户是否已经存在。通常,为了从平面文件插入数据,我使用字符串生成器来创建多个插入查询
这在一些要求较低的项目中效果很好,但现在我手头有一个更大的挑战。我需要创建一个每天导入新数据的网站,因此让“导入模块”遵循最佳实践非常重要
到目前为止我所做的:
- 我的数据库模型:大约20个具有各种关系的表(包括多对多)李>
- 使用实体模型代码生成器在APS.Net项目中生成相应的模型
- 执行批量数据插入,我这样做很慢,可能不安全李>
- 插入避免重复的数据,并使用外部表的正确ID李>
这就是为什么我需要你的帮助,我如何才能最好地利用现有的技术来实现我的目标?是否可以使用实体框架(EF)将帐户列表轻松添加到数据集中?假设您已正确映射数据库(代码优先或数据库优先),则应将少量表映射到您的上下文。例如:
public class DataModel : DbContext
{
/* more code ... */
public virtual DbSet<User> Users { get; set; }
/* more code ... */
}
用户将被插入到一个事务中(假设基础数据存储支持事务)。您的要求:
如果你使用EF从C代码中插入数据,你可以考虑使用参数化SQL查询,使你的插入从SQL注入攻击更安全。 使用
Data.SqlClient.SqlCommand.Parameters.Add
:
MSDN:
但是,如果使用SSI或T-SQL批量插入,则插入作业应该运行得更快
以下是我找到的资源:
- SQL Server集成服务(SSIS)
- 提取转换负载(ETL)
- (命令行)bcp实用程序
- (T-SQL)批量插入
- (T-SQL)插入。。。从OPENROWSET(批量…)中选择*
- 使用最小日志记录
- 将数据从多个客户端并行导入到单个表
- 使用批次
- 禁用触发器
- 禁用约束
- 对数据文件中的数据进行排序
- 控制锁定行为
- 以本机格式导入数据
- 未复制该表
- 指定了表锁定(使用TABLOCK)
- 表不是内存优化的表
- 如果该表没有索引,则记录的数据页最少
- 如果表没有聚集索引,但有一个或多个非聚集索引,则数据页的日志记录总是最少的。但是,索引页的记录方式取决于表是否为空:
- 如果表为空,则索引页的记录最少
- 若表为非空,则索引页将被完全记录
- 如果该表具有聚集索引且为空,则数据页和索引页的日志记录量都最小。相反,如果表具有聚集索引且非空,则无论采用何种恢复模式,数据页和索引页都会被完全记录
- 大容量插入-SQL Server 2005和2008
- 从OPENROWSET(大容量…)中插入…选择*-SQL Server 2005和2008
public class SomeClass
{
public int InsertUsers(params User[] users)
{
using(var context = new DataModel())
{
context.Users.AddRange(users);
}
}
}
public void InsertCustomer(Integer customerID, DateTime activityDate) {
String sql = "INSERT INTO Customers (customerID, ActivityDate) VALUES (@customerID, @activityDate);";
Data.SqlClient.SqlCommand cmd = new Data.SqlClient.SqlCommand(sql);
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("@customerID ", Data.SqlDbType.Int).Value = customerID;
cmd.Parameters.Add("@activityDate ", Data.SqlDbType.DateTime).Value = activityDate;
try {
using (SqlConnection connection = new Data.SqlClient.SqlConnection(YourConnectionString)) {
connection.Open();
cmd.Connection = connection;
cmd.ExecuteNonQuery();
}
} catch (Exception ex) {
throw ex;
}
}