<1>
例子:
public ActionResult Index()
{
DataTable dt = new DataTable();//在内存中创建一个DataTable
//给dt表添加四列
dt.Columns.Add("内存dt表列Id"); //Id是自增主键
dt.Columns.Add("内存dt表列Name");
dt.Columns.Add("内存dt表列Age");
dt.Columns.Add("内存dt表列Gender");
//遍历,将数组中的元素赋值给,在本地创建的dt表的对应row(行),for循环完毕以后dt表中就会有非常多的行了
for (int i = 0; i < 10000000; i++)
{
DataRow row = dt.NewRow(); //在dt表中创建一行
row["内存dt表列Name"] = "张三" + i; //给row行的字段(列)赋值
row["内存dt表列Age"] = 23;
row["内存dt表列Gender"] = 0;
dt.Rows.Add(row); //将这一行加入到dt表中
using (System.Data.SqlClient.SqlBulkCopy sqlBC = new System.Data.SqlClient.SqlBulkCopy("conn"))
{
sqlBC.BatchSize = 100000; //指示每10万条一个事务并提交
sqlBC.BulkCopyTimeout = 60; // 指示60秒按超时处理
sqlBC.DestinationTableName = "dbo.TableB"; //指示将数据导入TableB表
sqlBC.ColumnMappings.Add("内存dt表列Name", "Name");
sqlBC.ColumnMappings.Add("内存dt表列Age", "Age");
sqlBC.ColumnMappings.Add("内存dt表列Gender", "Gender");//指示将内存中dt表各字段与TableB中的各字段匹配
sqlBC.WriteToServer(dt); //写入数据库。其中dt是预先构建好的DataTable,其中包含valueA字段。
}
}
return View();
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.IO;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;
namespace 批量数据导入
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
public MainWindow()
{
InitializeComponent();
}
private void btnBigIData_Click(object sender, RoutedEventArgs e)
{
//在导入数据的时候删除数据库表中的所有数据
Helper.DAL.DeleteDataAll();
OpenFileDialog ofd = new OpenFileDialog();
//弹出一个对话框,让用户选要读取的文件,如果用户选中了文件
if (ofd.ShowDialog() == true)
{
//获取选中文件的完整路径。
string fileName = ofd.FileName;
//打开这个文件,并用指定的编码一行一行的读取这个路径的文件,读取完后关闭该文件(因为是一行一行的读取数据的,那么一行就是一个数组元素,文件里面有多行,所以得用个数组来保存读取到的文件数据)
string[] lines = File.ReadAllLines(fileName, Encoding.Default);
//在本地创建一个DataTable
DataTable dt = new DataTable();
//给dt表添加四列
dt.Columns.Add("本地dt表列Section");
dt.Columns.Add("本地dt表列Area");
dt.Columns.Add("本地dt表列NumberType");
dt.Columns.Add("本地dt表列AreaCode");
//遍历刚刚读取到的文件行数组,将数组中的元素赋值给,在本地创建的dt表的对应row(行),for循环完毕以后dt表中就会有非常多的行了
for (int i = 0; i < lines.Length; i++)
{
string[] line = lines[i].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
string Section = line[0].Trim();
string Area = line[1].Trim();
string NumberType = line[2].Trim();
string AreaCode = line[3].Trim();
//在dt表中创建一行
DataRow row = dt.NewRow();
//给row行的字段(列)赋值
row["本地dt表列Section"] = Section;
row["本地dt表列Area"] = Area;
row["本地dt表列NumberType"] = NumberType;
row["本地dt表列AreaCode"] = AreaCode;
//将这一行加入到dt表中
dt.Rows.Add(row);
}
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(this.connStr))
{
//你要把数据批量插入数据库的哪个表中?
bulkCopy.DestinationTableName = "T_Mobile";
//下面建立本地dt表字段,与数据库表之间的映射关系
//第一个参数是自己在本地建立的dt表里的列名,第二个参数是数据库中表的对应列名
bulkCopy.ColumnMappings.Add("本地dt表列Section", "Section");
bulkCopy.ColumnMappings.Add("本地dt表列Area", "Area");
bulkCopy.ColumnMappings.Add("本地dt表列NumberType", "NumberType");
bulkCopy.ColumnMappings.Add("本地dt表列AreaCode", "AreaCode");
//将dt表放入到数据库中
bulkCopy.WriteToServer(dt);
MessageBox.Show("插入完毕");
}
}
}
}
}
DAL
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Helper
{
public class DAL
{
public static void DeleteDataAll()
{
SqlHelper.ExecuteNonQuery("delete from T_Mobile");
}
}
}
SqlHelper
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
using System.Reflection;
namespace Helper
{
public class SqlHelper
{
/// <summary>
/// 获取连接数据库字符串
/// </summary>
private static string connStr=ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
/// <summary>
/// 对连接执行 Transact-SQL 语句并返回受影响的行数
/// </summary>
/// <param name="sql">对数据库表进行Insert,Update和Delete语句</param>
/// <param name="parameters">sql语句参数</param>
/// <returns>返回值为该命令所影响的行数</returns>
public static int ExecuteNonQuery(string sql ,params SqlParameter[] parameters)
{
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
int i= cmd.ExecuteNonQuery();
return i;
}
}
}
/// <summary>
/// 执行查询,并返回查询所返回的结果集中第一行的第一列。一般用于SQL聚合函数,如:count,Max,min,avg。。
/// </summary>
/// <param name="sql">要执行的sql语句</param>
/// <param name="parameters">sql语句的参数</param>
/// <returns>返回查询所返回的结果集中第一行的第一列。忽略其他列或行。返回的最大字符数为 2033 个字符。</returns>
public static object ExecuteScalar(string sql, params SqlParameter[] parameters)
{
using (SqlConnection conn=new SqlConnection (connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
//ExcuteScalar()的返回值是object类型的(如果想返回int类型的数据,可先将cmd.ExecuteSalar()转化成int类型再进行返回)
return cmd.ExecuteScalar();
}
}
}
/// <summary>
/// DataSet是将查询结果填充到本地内存中,这样即使与连接断开,服务器的连接断开,都不会影响数据的读取。但是它也有一个坏处,就是只有小数据量才能往里面存放,数据量大了就给你的本地内存冲爆了。电脑会卡死去。大数据量的话还得用SqlDataReader
/// </summary>
/// <param name="sql">要执行的sql语句</param>
/// <param name="parameters">sql语句的参数</param>
/// <returns>返回值是一个DataSet</returns>
public static DataSet ExecuteDataSet(string sql, params SqlParameter[] parameters)
{
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
DataSet ds=new DataSet();
using(SqlDataAdapter adapter=new SqlDataAdapter (cmd))
{
//将cmd的执行结果填充到ds里面
adapter.Fill(ds);
return ds;
}
}
}
}
/// <summary>
/// 执行查询,并将查询的结果以DataTable的形式返回
/// </summary>
/// <param name="sql">要执行的sql语句</param>
/// <param name="parameters">sql语句的参数</param>
/// <returns>返回值是一个DataTable</returns>
public static DataTable ExecuteDataTable(string sql, params SqlParameter[] parameters)
{
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
//换一种写法,与上面的几种写法稍稍有点不同
using (SqlCommand cmd = new SqlCommand(sql ,conn))
{
cmd.Parameters.AddRange(parameters);
DataTable dt = new DataTable();
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
adapter.Fill(dt);
return dt;
}
}
}
}
/// <summary>
/// 将查询的结果转换成一个T类型的对象
/// </summary>
/// <typeparam name="T">泛型类T</typeparam>
/// <param name="sql">要执行的sql语句</param>
/// <param name="parameters">sql语句的参数</param>
/// <returns>T类型的对象</returns>
public static List<T> ExecuteClass<T>(string sql, params SqlParameter[] parameters)
{
List<T> list = new List<T>();
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
DataSet ds = new DataSet();
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
adapter.Fill(ds);
}
//获取ds里面的第0个表(索引从0开始)
DataTable dt = ds.Tables[0];
//获取T类型的所有公有属性
PropertyInfo[] tMembers= typeof(T).GetProperties();
//遍历dt表的所有行
for(int i=0;i <dt.Rows.Count;i ++)
{
//创建一个泛型T类型的对象t。
T t = Activator.CreateInstance<T>();
//遍历dt表的所有列
for (int j = 0; j < dt.Columns.Count; j++)
{
//遍历T类型的所有公有属性
foreach (PropertyInfo tMember in tMembers)
{
//如果发现dt表中的列名与遍历出来的T类型属性名相同
if (dt.Columns[j].ColumnName.ToUpper().Equals(tMember.Name.ToUpper()))
{
//将dt.Rows[i][j]赋值给t对象的tMember成员
if (dt.Rows[i][j] != DBNull.Value)
{
tMember.SetValue(t, dt.Rows[i][j], null);
}
else
{
tMember.SetValue(t, null, null);
}
break;//;//注意这里的break是写在if语句里面的,意思就是说如果列名和属性名称相同并且已经赋值了,那么我就跳出foreach循环,进行j+1的下次循环
}
}
}
list.Add(t);
}
return list;
}
}
}
/*
public static object ExecuteDataReader(string sql, params SqlParameter[] paramters)
{
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using(SqlCommand cmd=new SqlCommand(sql,conn))
{
cmd.Parameters.AddRange(paramters);
using (SqlDataReader dr = cmd.ExecuteReader())
{
if (dr.Read()==true)
{
}
}
}
}
}
*/
/// <summary>
/// 从数据库取值赋给.net类的对象属性,如果值为DBNull.Value,则将值转换成.Net认的null
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static object FromDbValue(object value)
{
if (value == DBNull.Value)
{
return null;
}
else
{
return value;
}
}
/// <summary>
/// 将.net类对象的属性值插入到数据库,如果类的属性值为null,则将值转换成数据库认的DBNull.value
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static object ToDbValue(object value)
{
if (value == null)
{
return DBNull.Value;
}
else
{
return value;
}
}
}
}
例2
public AjaxResult SaveNewsInfo(DSYPFakeNewsInfoViewModel model)
{
AjaxResult ajaxResult = new AjaxResult() { Code = 1, Detail = "保存成功" };
if (model != null && model.NewData != null)
{
var news = model.NewData.Split(new string[] { "(;3)" }, StringSplitOptions.RemoveEmptyEntries);
SqlConnection conn = new SqlConnection(UnitOfWork.GetConnectionString());
DataTable dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("WebSiteID", typeof(int));
dt.Columns.Add("SearchKeyName", typeof(string));
dt.Columns.Add("NewTitle", typeof(string));
dt.Columns.Add("NewContent", typeof(string));
foreach (var item in news)
{
DataRow dr = dt.NewRow();
dr["WebSiteID"] = model.WebSiteId;
dr["SearchKeyName"] = model.SearchKeyName;
dr["NewTitle"] = item[0];
dr["NewContent"] = item[1];
dt.Rows.Add(dr);
}
try
{
conn.Open();
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn))
{
bulkCopy.DestinationTableName = "DSYPFakeNewsInfo";
bulkCopy.ColumnMappings.Add("WebSiteID", "WebSiteID");
bulkCopy.ColumnMappings.Add("SearchKeyName", "SearchKeyName");
bulkCopy.ColumnMappings.Add("NewTitle", "NewTitle");
bulkCopy.ColumnMappings.Add("WebColumnId", "WebColumnId");
bulkCopy.ColumnMappings.Add("NewContent", "NewContent");
bulkCopy.BatchSize = dt.Rows.Count;
bulkCopy.WriteToServer(dt);
}
}
catch (Exception ex)
{
ajaxResult.Code = -1;
ajaxResult.Detail = "保存失败";
}
finally
{
conn.Close();
}
}
return ajaxResult;
}