using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YX.Entity; namespace YX.DAL.Extenstions
{
public static class SqlBulkCopyHelper
{
public static void BulkInsertAll<T>(IEnumerable<T> entities)
{
entities = entities.ToArray();
var cons = new Sam_DBEntities();
string cs = cons.Database.Connection.ConnectionString;
var conn = new SqlConnection(cs);
conn.Open(); Type t = typeof(T); var bulkCopy = new SqlBulkCopy(conn)
{
DestinationTableName = t.Name
}; var properties = t.GetProperties().Where(EventTypeFilter).ToArray();
var table = new DataTable(); foreach (var property in properties)
{ Type propertyType = property.PropertyType;
if (propertyType.IsGenericType &&
propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
propertyType = Nullable.GetUnderlyingType(propertyType);
} table.Columns.Add(new DataColumn(property.Name, propertyType));
} foreach (var entity in entities)
{ table.Rows.Add(properties.Select(
property => GetPropertyValue(
property.GetValue(entity, null), property.PropertyType.Name)).ToArray());
}
foreach (DataColumn dc in table.Columns)
{
bulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping(dc.ColumnName, dc.ColumnName));
}
bulkCopy.WriteToServer(table); conn.Close();
} private static bool EventTypeFilter(System.Reflection.PropertyInfo p)
{
var attribute = Attribute.GetCustomAttribute(p,
typeof(AssociationAttribute)) as AssociationAttribute; if (attribute == null) return true;
if (attribute.IsForeignKey == false) return true; return false;
} private static object GetPropertyValue(object o, string type)
{
if (o == null)
{
return DBNull.Value;
} return o;
}
}
}

今天使用SqlBulkCopy时,一直报错。

错误信息如下

来自数据源的 String 类型的给定值不能转换为指定目标列的类型 datetime。 ---> System.FormatException: 将参数值从 String 转换到 DateTime 失败。 ---> System.FormatException: 该字符串未被识别为有效的 DateTime。

我就开始检查这个表中的时间字段,结果检查了N次之后,发现所有插入表中的DateTime都是正确的。

后来在尝试其他方法后,发现由于我使用的DataTable中未包含自增长的列,加上自增列之后,就正确插入到数据库中了。

分析了一下,应该是列对应错误,

SqlBulkCopy不是根据表的ColumnName来匹配的,而是根据ColumnIndex匹配。所以插入数据的表需要和数据库中表的列名顺序完全一致

如果需要按照ColumnName对应来插入数据,可以指定SqlBulkCopyColumnMapping。代码如下

 SqlBulkCopy sbc = new SqlBulkCopy(conPrivate);

 foreach (DataColumn dc in dt.Columns)
sbc.ColumnMappings.Add(new SqlBulkCopyColumnMapping(dc.ColumnName, dc.ColumnName));

EF中使用SqlBulkCopy的更多相关文章

  1. EF中的那些批量操作

    在使用EF的过程中,我们经常会遇到需要批量操作数据的场景,批量操作有的时候不仅能提高性能,比如使用SqlBulkCopy进入批量插入的时候,而且比较方便操作,提高效率.那么这篇文章就来总结EF中的那些 ...

  2. EF中的批量操作

    阅读目录 插入 更新 删除 在使用EF的过程中,我们经常会遇到需要批量操作数据的场景,批量操作有的时候不仅能提高性能,比如使用SqlBulkCopy进入批量插入的时候,而且比较方便操作,提高效率.那么 ...

  3. 1.【使用EF Code-First方式和Fluent API来探讨EF中的关系】

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/relationship-in-entity-framework-using-code-firs ...

  4. 2.EF中 Code-First 方式的数据库迁移

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/code-first-migrations-with-entity-framework/ 系列目 ...

  5. EF中扩展出Between操作符 (修订版)

    随手记录一下,这是针对原文错误的修改. 原文:EF中扩展出Between操作符 直接使用是错误的,修改后的扩展方法: /// <summary> /// 扩展 Between 操作符 // ...

  6. 如何在EF中实现left join(左联接)查询

    在EF中,当在dbset使用join关联多表查询时,连接查询的表如果没有建立相应的外键关系时,EF生成的SQL语句是inner join(内联),对于inner join,有所了解的同学都知道,很多时 ...

  7. sql 中的Bulk和C# 中的SqlBulkCopy批量插入数据 ( 回顾 and 粗谈 )

    通常,我们会对于一个文本文件数据导入到数据库中,不多说,上代码. 首先,表结构如下.   其次,在我当前D盘中有个文本文件名为2.txt的文件. 在数据库中,可以这样通过一句代码插入. Bulk in ...

  8. EF中执行sql语句,以及事务

    EF to sql string sql = "select T_Task.BSID,T_Task.CloseDate,T_Task.CompleteDate,T_Task.CloseUse ...

  9. EF架构~在ef中支持IQueryable级别的Contains被翻译成了Exists,性能可以接受!

    回到目录 Entityframeworks很聪明 不错,非常不错!ef里的contains比linq to sql里的contains有了明显的提升,事实上,是在进行SQL语句翻译上有所提升,在lin ...

  10. DB表的关系及EF中Fluent API的使用

    现在使用多数的数据库是关系型数据库,那么表与表之间的关系就会显得尤其重要,对于数据的CRUD处理和以后数据的分析有很大的好处.下面是对于数据库中对表关系的理解以及在EF中使用Fluent API来创建 ...

随机推荐

  1. Grafana 系列文章(六):Grafana Explore 中的日志

    ️URL: https://grafana.com/docs/grafana/latest/explore/logs-integration/#labels-and-detected-fields D ...

  2. wangeditor富文本编辑和vue3

    官网: wangEditor  https://www.wangeditor.com/v5/ 为啥用这个富文本编辑器(我觉得官网写自己优势已经非常好了没有啥可补充的了) 文档特别的全和友好 安装 ya ...

  3. 浅谈Pytest中的warning处理

    浅谈Pytest中的warning处理 没有处理warning 我们写一个简单的测试 import pytest def test_demo(): import warnings warnings.w ...

  4. mvn引用本地包

    <dependency> <groupId>jna</groupId> <artifactId>jna</artifactId> <s ...

  5. vue3 h函数 h() 生成 element-plus vnode

    vue3的h函数和vue2的h函数入参不同 下面是vue2的vnode示范 然后是vue3的错误示范 下面是正确示范 let open1=() => { return new Promise(( ...

  6. Windows 10 企业版 LSTC 激活秘钥及方法

    Windows 10 企业版 LSTC 秘钥:M7XTQ-FN8P6-TTKYV-9D4CC-J462D 同时按下Win键+X,然后选择Windows PowerShell(管理员)按顺序输入下面的字 ...

  7. osx安装mpd和ncmpcpp

    简介 mdp 是一款开源的音乐播放软件, 全名为 media player daemon , 从字面意思理解, 就是一个后台播放进程. 不同于传统的音乐播放软件集成了播放解码和界面, mpd 只是一个 ...

  8. python3 os.getcwd()和os.path.realpath()区别

    在写一个android手机的自动化测试,用appium+python3,跟室友讨论拟定了一个框架,在写2个通用的简单模块时,遇到问题. 同一个目录下2个模块,driver.py(用于获取app 句柄) ...

  9. 关于Promise.all()的理解

    本篇笔记是抄的别人的,目的只是为了日后有用到时有个参考,原文地址是https://www.jianshu.com/p/7e60fc1be1b2 一.Pomise.all的使用 Promise.all可 ...

  10. MVC3三层架构

    以上部分来自黑马