EF中的那些批量操作

在使用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 }

时间: 2024-10-14 23:14:00

EF中的那些批量操作的相关文章

[转载]EF中的那些批量操作

阅读目录 插入 更新 删除 在使用EF的过程中,我们经常会遇到需要批量操作数据的场景,批量操作有的时候不仅能提高性能,比如使用SqlBulkCopy进入批量插入的时候,而且比较方便操作,提高效率.那么这篇文章就来总结EF中的那些批量操作. 回到顶部 插入 1,单个插入 单个插入很简单,只需要构造好实体,然后调用DbSet的Add方法,最后SaveChanges就行,示例代码如下. using (var db = new PackageFHContext()) { // 单个插入 var enti

EF中的批量操作

阅读目录 插入 更新 删除 在使用EF的过程中,我们经常会遇到需要批量操作数据的场景,批量操作有的时候不仅能提高性能,比如使用SqlBulkCopy进入批量插入的时候,而且比较方便操作,提高效率.那么这篇文章就来总结EF中的那些批量操作. 回到顶部 插入 1,单个插入 单个插入很简单,只需要构造好实体,然后调用DbSet的Add方法,最后SaveChanges就行,示例代码如下. using (var db = new PackageFHContext()) { // 单个插入 var enti

EF中执行sql语句

EF原理 EF 会自动把 Where().OrderBy().Select()等这些编译成"表达式树(Expression Tree)",然后会把表达式树翻译成 SQL 语句去执行.(编译原理,AST)因此不是"把数据都取到内存中,然后使用集合的方法进行数据过滤",因此性能不会低.但是如果这个操作不能被翻译成 SQL 语句,则或者报错,或者被放到内存中操作,性能就会非常低 跟踪EF的查询Sql语句: DbContext 有一个 Database 属性,其中的 Log

EF中三大开发模式之DB First,Model First,Code First以及在Production Environment中的抉择

一:ef中的三种开发方式 1. db first... db放在第一位,在我们开发之前必须要有完整的database,实际开发中用到最多的... <1> DBset集合的单复数... db => model 2. model first... 根据model生成数据库,和我们的sqlserver的可视化类视图是一样的... 其实sqlserver也是有自己的类视图... 如果用ef来创建: <1> 生成类图.. <2> 根据模型生成数据库... 3. code f

EF中逆变和协变

EF中的增删改查: 实现步骤: 1.声明一个EF的上下文. bjhksjEntities dbContext = new bjhksjEntities(); 2.声明一个实体. HKSJ_USERS user = new HKSJ_USERS(); user.LoginName = "ssss"; user.Mail = "ssss"; user.PassWord = "ssss"; user.Plane = "ssss";

数据库事务及其EF中如何处理事务

一.基础知识 1)         使用事务级别ReadUnCommited 会产生脏读现像,意味着读取到的为UnCommited(未提交)的数据.怎么理解呢?在使用该隔离级别的事务开始后.更新了数据库某一行的数据,但是事务的工作量比较大,后续还有一大堆代码还没执行完呢.不巧的是有个哥们过来读数据了,这个时候读到的就是未提交的值,如果后继工作一切正常,也没什么影响.一旦后面的代码执行中出错,就会产生不一致的错误,适用于对事务极度自信的情况下,特点为可读不可改.关于不可改需解释一下,MS SQL中

EF中的增删改查

在上一篇中简单的介绍了一下有关EF的一些概念,都是小编的一些个人理解,懂的不多,想深入学习的可以从网上查看一些其他资料. 下面紧接着上一篇所说,来从代码上看一下EF容器是如何实现与后台数据库之间的增删改查的. 1.EF包装类 什么是EF包装类呢?举个例子,我们平时用SQL语句写增删改查时,用的都是一些Insert.Update.Delete等语句来实现增删改查,所以我们把放到EF容器的东东也要做一个标签,来指明这个东东是要添加.更新.还是要删除呢. 正如上图所示就是这么简单的操作,就完成了对数据

EF中Database.SqlQuery

本文转载:http://www.cnblogs.com/daimage/archive/2012/07/04/2575844.html EF中Database.SqlQuery<TElement> Method (String, Object[]) 可以直接执行SQL语句 但以为object[]参数和在ado.net中一样呢 开始就按ADO.NET中的 写法 sql为:update Product_Union set [email protected] where [email protect

EF中执行存储过程

SqlParameter[] parms = new SqlParameter[5]; SqlParameter parms0 = new SqlParameter("IsAll", int.Parse(parames.P1)); //生成一个参数并给参数赋值. SqlParameter parms1 = new SqlParameter("ForumId", int.Parse(parames.P2)); SqlParameter parms2 = new Sql