阅读目录

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

插入

1,单个插入

单个插入很简单,只需要构造好实体,然后调用DbSet的Add方法,最后SaveChanges就行,示例代码如下。

using (var db = new PackageFHContext())
{
// 单个插入
var entity = new ProdImage
{
ProductID = 1807,
Type = 7,
Priority = 0,
Url = " http://www.baidu.com/abc.png",
Alt = "test",
Creator = "system",
CreateOn = DateTime.Now
};
db.ProdImageSet.Add(entity);
db.SaveChanges();
}

2,批量插入

很多时候我们需要向同一数据表插入大量的数据,如果插入一条就调一次SaveChanges这样性能很低,需要频繁地访问数据库。为了解决这个问题,可以使用SqlBulkCopy来批量插入数据,这样很大地提高性能。示例代码如下。

using (var db = new PackageFHContext())
{
// 批量插入(使用到SqlBulkCopy)
var prodImages = new List<ProdImage>();
for (int i = 0; i < 50; i++)
{
prodImages.Add(new ProdImage
{
ProductID = 1807,
Type = 7,
Priority = 0,
Url = " http://www.baidu.com/abc.png",
Alt = "test" + i,
Creator = "system",
CreateOn = DateTime.Now
});
} if (db.Database.Connection.State != ConnectionState.Open)
{
db.Database.Connection.Open();
} PackageFH.Common.DBHelper.BulkInsert((SqlConnection)db.Database.Connection, "dbo.Pkg_ProdImage", prodImages); if (db.Database.Connection.State != ConnectionState.Closed)
{
db.Database.Connection.Close();
}
}

当然SqlBulkCopy的操作封装在了DBHelper中了,后面会附上DBHelper.BulkInsert的实现。

更新

1,单个更新

单个更新很简单,只需要先查询出那条数据,然后修改字段的值,最后SaveChanges就行。示例代码如下。

using (var db = new PackageFHContext())
{
// 单个更新
var entity = db.ProdImageSet.FirstOrDefault(p => p.ImageID == 275695);
entity.Alt = "ooooooooooo";
db.SaveChanges();
}

2,批量更新

我们可以先查找要更新的那些记录,然后遍历修改字段的值,最后调用SaveChanges提交更新。示例代码如下。

using (var db = new PackageFHContext())
{
// 批量更新
var entitys = db.ProdImageSet.Where(p => p.ProductID == 1807 && p.Type == 7);
var j = 1;
entitys.ToList().ForEach(item =>
{
item.Alt = "update test" + j;
db.Entry(item).State = System.Data.Entity.EntityState.Modified; //不加这句也可以,为什么?
j++;
});
db.SaveChanges();
}

通过SQL Profiler监控可以看到,最后生成的还是很多的UPDATE语句,也就是说每更新一条就是一个UPDATE语句。

删除

1,单个删除

示例代码如下。

using (var db = new PackageFHContext())
{
// 单个删除
var entity = db.ProdImageSet.FirstOrDefault(p => p.ImageID == 275695);
db.ProdImageSet.Remove(entity);
db.SaveChanges();
}

2,批量删除

示例代码如下。

using (var db = new PackageFHContext())
{
// 批量删除
var entitys = db.ProdImageSet.Where(p => p.ProductID == 1783 && p.Type == 0);
entitys.ToList().ForEach(entity => db.Entry(entity).State = System.Data.Entity.EntityState.Deleted); //不加这句也可以,为什么?
db.ProdImageSet.RemoveRange(entitys);
db.SaveChanges();
}

通过SQL Profiler监控,结果生成的也是多条DELETE语句。

附:DBHelper.BulkInsert的实现代码

 1 public static void BulkInsert<T>(SqlConnection conn, string tableName, IList<T> list)
2 {
3 using (var bulkCopy = new SqlBulkCopy(conn))
4 {
5 bulkCopy.BatchSize = list.Count;
6 bulkCopy.DestinationTableName = tableName;
7
8 var table = new DataTable();
9 var props = TypeDescriptor.GetProperties(typeof(T), new Attribute[] { new DatabaseTableColumnAttribute() })
10 //Dirty hack to make sure we only have system data types
11 //i.e. filter out the relationships/collections
12 .Cast<PropertyDescriptor>()
13 .Where(propertyInfo => propertyInfo.PropertyType.Namespace.Equals("System"))
14 .ToArray();
15
16 foreach (var propertyInfo in props)
17 {
18 bulkCopy.ColumnMappings.Add(propertyInfo.Name, propertyInfo.Name);
19 table.Columns.Add(propertyInfo.Name, Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType);
20 }
21
22 var values = new object[props.Length];
23 foreach (var item in list)
24 {
25 for (var i = 0; i < values.Length; i++)
26 {
27 values[i] = props[i].GetValue(item);
28 }
29
30 table.Rows.Add(values);
31 }
32
33 bulkCopy.WriteToServer(table);
34 }
35 }

EF中的批量操作的更多相关文章

  1. EF中的那些批量操作

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. EF 中事务的书写

    在EF 中怎么使用事务? 这个问题纠结了我好久,直到有人跟我一起讨论,我和同事一起讨论查资料. 查的好多资料都是使用 using (TransactionScope scope = new Trans ...

随机推荐

  1. How to use NSRequest in Delphi XE4

    //Demo How to use NSRequest..procedure TiOSWebBrowserService.DoNavigate(const URL: string);var NewUR ...

  2. 利用Python进行文章特征提取(一)

    # 文字特征提取 词库模型(bag of words) 2016年2月26,星期五 # 1.词库表示法 In [9]: # sklearn 的 CountVectorizer类能够把文档词块化(tok ...

  3. 伪元素:placeholder-shown&&:focus-within

    :placeholder-shown 另外,划重点,这个伪类是仍处于实验室的方案.也就是未纳入标准,当然我们的目的是探寻有意思的 CSS . 当 input 类型标签使用了 placeholder 属 ...

  4. HDU - 5088: Revenge of Nim II (问是否存在子集的异或为0)

    Nim is a mathematical game of strategy in which two players take turns removing objects from distinc ...

  5. 关于altera的fft核使用问题记录

    altera的fft核使用比较特别,今天我做了一下仿真,发现一些问题,现做记录如下: 1,ip配置 parameters选项卡主要是fft变换的长度和数据长度,旋转因子长度,需要注意的是“Twiddl ...

  6. 洛谷P1979 华容道

    神の契约 题目大意:自己看去... 题解:做了一下午...本蒟蒻立志要写全网最详细的题解.╭(╯^╰)╮ begin.... 暴力70分.可以让空格子到处乱走,只要某个状态的指定格子到目标格子,那么此 ...

  7. springboot 自定义属性

    前言 spring boot使用application.properties默认了很多配置.但需要自己添加一些配置的时候,我们如何添加呢 1.添加自定义属性 在src/main/resources/a ...

  8. 脚本工具---自动解析mysql建表语句,生成sqlalchemy表对象声明

    常规建表语句: CREATE TABLE `test_table` ( `id` int(11) NOT NULL, `name` char(64) NOT NULL, `password` char ...

  9. DataGrid方法标注

    在VS2010中无法增加了CColumn和Ccolumns类 解决方案,方案名->右击->添加类->ActiveX控件中的MFC类->添加弹出了“从ActiveX控件添加类向导 ...

  10. biosdevname网卡命名方式

    在前天通过了最后的 Go/No-Go 会议后,Fedora 15 已定于下周正式发布,这个永远站在开源技术最前沿的发行版,即将迎来又一个新的大的变动.作为 Fedora 用户,相信你已经习惯了每个新版 ...