威尼斯人线上娱乐

EF中的批量操作,Dapper批量操作实体

17 4月 , 2019  

EF中的批量操作,Dapper批量操作实体。率先要设置 Dapper.Contrib,直接从nuget安装就能够。

回去目录

翻阅目录

在采纳EF的历程中,我们平时会遇上必要批量操作数据的光景,批量操作有的时候不仅能增高质量,比如利用SqlBulkCopy进入批量插入的时候,而且比较便利操作,进步效能。那么那篇小说就来总括EF中的那一个批量操作。

dapper官方文书档案:

说它是批量操作,实属将聚集对象三次提交到服务器,并对数码举行持久化,假设你的代码是3遍一回的交付,那不算是批量操作!在头里的mongodb仓库储存中并未对批量更新和批量剔除实行落到实处,而明日在项目中,依然促成了那种批量的操作,并且已经因而测试,上边公开一下源代码

  • 插入
  • 更新
  • 删除

插入

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的兑现。

T Get<T>(id);
IEnumerable<T> GetAll<T>();
int Insert<T>(T obj);
int Insert<T>(Enumerable<T> list);
bool Update<T>(T obj);
bool Update<T>(Enumerable<T> list);
bool Delete<T>(T obj);
bool Delete<T>(Enumerable<T> list);
bool DeleteAll<T>();
        public void Insert(IEnumerable<TEntity> item)
        {
            var list = new List<WriteModel<TEntity>>();
            foreach (var iitem in item)
            {
                list.Add(new InsertOneModel<TEntity>(iitem));
            }
            _table.BulkWriteAsync(list).Wait();
        }

        public void Update(IEnumerable<TEntity> item)
        {

            var list = new List<WriteModel<TEntity>>();

            foreach (var iitem in item)
            {
                QueryDocument queryDocument = new QueryDocument("_id", new ObjectId(typeof(TEntity).GetProperty(EntityKey).GetValue(iitem).ToString()));
                list.Add(new UpdateOneModel<TEntity>(queryDocument, Builders<TEntity>.Update.Combine(GeneratorMongoUpdate(iitem))));
            }
            _table.BulkWriteAsync(list).Wait();
        }

        public void Delete(IEnumerable<TEntity> item)
        {
            var list = new List<WriteModel<TEntity>>();

            foreach (var iitem in item)
            {
                QueryDocument queryDocument = new QueryDocument("_id", new ObjectId(typeof(TEntity).GetProperty(EntityKey).GetValue(iitem).ToString()));
                list.Add(new DeleteOneModel<TEntity>(queryDocument));
            }
            _table.BulkWriteAsync(list).Wait();
        }

在应用EF的经过中,大家经常会遇见须求批量操作数据的光景,批量操作有的时候不但能加强品质,比如利用SqlBulkCopy进入批量布置的时候,而且比较有利操作,进步功能。那么那篇文章就来总计EF中的那1个批量操作。

更新

一,单个更新

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

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

二,批量立异

大家能够先物色要创新的那一个记录,然后遍历修改字段的值,最终调用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语句,也即是说每更新一条就是3个UPDATE语句。

支撑插入、更新实体,批量插入、批量翻新实体。

在程序实现之中,大家选拔了WriteModel泛型对象,那将积存要插入,更新和删除的靶子,对于插入来讲,唯有贰个参数就是它的实体集合,而指标更新来讲,它不仅有实体集合而且还有相应的原则QueryDocument,而对于删除操作来讲,只提供QueryDocument就可以!

归来顶部

删除

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威尼斯人线上娱乐 2

 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

回到目录

插入

威尼斯人线上娱乐 ,壹,单个插入

单个插入相当的粗略,只须求组织好实体,然后调用DbSet的Add方法,最终SaveChanges就行,示例代码如下。

威尼斯人线上娱乐 3

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(); 
}

威尼斯人线上娱乐 4

2,批量铺排

成都百货上千时候我们需求向平等数据表插入大量的数量,如若插入一条就调2次SaveChanges那样品质十分低,需求频繁地拜会数据库。为了化解这些难点,能够采纳SqlBulkCopy来批量插入数据,那样十分大地进步品质。示例代码如下。

威尼斯人线上娱乐 5

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(); 
    } 
}

威尼斯人线上娱乐 6

本来SqlBulkCopy的操作封装在了DBHelper中了,前面会附着DBHelper.BulkInsert的落到实处。

再次来到顶部

更新

一,单个更新

单个更新不会细小略,只必要先查询出那条数据,然后修改字段的值,最终SaveChanges就行。示例代码如下。

威尼斯人线上娱乐 7

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

威尼斯人线上娱乐 8

二,批量更新

大家得以先找找要更新的那几个记录,然后遍历修改字段的值,最后调用SaveChanges提交更新。示例代码如下。

威尼斯人线上娱乐 9

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();
}

威尼斯人线上娱乐 10

透过SQL
Profiler监察和控制能够看出,最一生成的照旧众多的UPDATE语句,也便是说每更新一条正是二个UPDATE语句。

归来顶部

删除

1,单个删除

示范代码如下。

威尼斯人线上娱乐 11

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

威尼斯人线上娱乐 12

二,批量删减

示范代码如下。

威尼斯人线上娱乐 13

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();
}

威尼斯人线上娱乐 14

透过SQL Profiler监察和控制,结果生成的也是多条DELETE语句。

附:DBHelper.BulkInsert的兑今世码

威尼斯人线上娱乐 15

威尼斯人线上娱乐 16

 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 }

威尼斯人线上娱乐 17


相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图