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的实现代码

EF中的那些批量操作
 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 }
View Code

你可能感兴趣的:(批量操作)