阅读目录

在使用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. Django应用部署

    前言 Apachewsgi 环境搭建 安装Apache 安装mod_wsgi 添加djangowsgi文件 配置etcapache2httpdconf wsgipy配置 跑起来吧 uWSGI 环境搭建 ...

  2. VS2017连接到中国区的Azure

    1. 安装Azure Environment Select扩展 2. 选择中国区的Azure 3. 之后就可以使用中国区的账号登录了 参考链接:https://docs.azure.cn/zh-cn/ ...

  3. NGUI 学习使用

    http://www.tasharen.com/forum/index.php?board=12.0

  4. HDU - 6166:Senior Pan(顶点集合最短路&二进制分组)

    Senior Pan fails in his discrete math exam again. So he asks Master ZKC to give him graph theory pro ...

  5. HihoCoder 1121 二分图一•二分图判定

    二分图一•二分图判定 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 大家好,我是小Hi和小Ho的小伙伴Nettle,从这个星期开始由我来完成我们的Weekly. 新年回 ...

  6. Python之contextlib库及源码分析

    Utilities for with-statement contexts __all__ = ["contextmanager", "closing", &q ...

  7. 【mssql】SQL Server2012编程入门经典(第四版)(上) 读书笔记

    数据库用了很久了,但好多东西很容易忘记,这次头脑发热想起来读一遍书,做点笔记! 从第五章开始参考:<SQL Server 2005 编程入门经典>学习笔记 一.RDBMS基础:SQL Se ...

  8. 洛谷 P3015 [USACO11FEB]最好的括号Best Parenthesis

    传送门 题目大意:给出括号的得分标准. ()得分为1,如果A的得分为S(A),那么 (A)的得分为2*S(A). 题解:搜索 #include<iostream> #include< ...

  9. NOIP2013DAY1题解

    T1转圈游戏 十月のsecret 题解:快速幂 代码: #include<iostream> #include<cstring> #include<cstdio> ...

  10. spring--Autowired setter 方法

    在Spring中,可以使用 @Autowired 注解通过setter方法,构造函数或字段自动装配Bean.此外,它可以在一个特定的bean属性自动装配. 注 @Autowired注解是通过匹配数据类 ...