Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这是使用Dapper进行批量插入的有效方法吗?_C#_.net_Database_Insert_Dapper - Fatal编程技术网

C# 这是使用Dapper进行批量插入的有效方法吗?

C# 这是使用Dapper进行批量插入的有效方法吗?,c#,.net,database,insert,dapper,C#,.net,Database,Insert,Dapper,这是使用Dapper进行批量插入的有效方法吗 此外,这是否比创建存储过程并向其传递模型更有效 category = new Category { Name = "category", Description = "description", Created = null, LastM

这是使用Dapper进行批量插入的有效方法吗

此外,这是否比创建存储过程并向其传递模型更有效

            category = new Category
            {
                Name = "category",
                Description = "description",
                Created = null,
                LastModified = null,
                CategoryPictures = new CategoryPicture[]
                {
                    new CategoryPicture
                    {
                        CategoryId = 3,
                        PictureId = 2,
                        Picture = new Picture
                        {
                            Url = "newUrl"
                        }
                    },
                      new CategoryPicture
                    {
                        CategoryId = 3,
                        PictureId = 2,
                        Picture = new Picture
                        {
                            Url = "url"
                        }
                    }
                }
            };

            string sql = @"INSERT INTO Categories(Name, Description, Created, LastModified)
                           VALUES(@Name, @Description, @Created, @LastModified)";

            await conn.ExecuteAsync(sql, new
            {
                category.Name,
                category.Description,
                category.Created,
                category.LastModified
            });

            string catPicInsert = @"INSERT INTO CategoryPictures(fk_CategoryId, fk_PictureId)
                           VALUES(@CategoryId, @PictureId)";

            await conn.ExecuteAsync(catPicInsert, category.CategoryPictures);

            string PicInsert = @"INSERT INTO Pictures(Url)
                           VALUES(@Url)";

            await conn.ExecuteAsync(PicInsert, category.CategoryPictures.Select(x => 
                                                                              x.Picture).ToList());
这是使用Dapper进行批量插入的有效方法吗? 此外,这是否比创建存储过程并向其传递模型更有效

            category = new Category
            {
                Name = "category",
                Description = "description",
                Created = null,
                LastModified = null,
                CategoryPictures = new CategoryPicture[]
                {
                    new CategoryPicture
                    {
                        CategoryId = 3,
                        PictureId = 2,
                        Picture = new Picture
                        {
                            Url = "newUrl"
                        }
                    },
                      new CategoryPicture
                    {
                        CategoryId = 3,
                        PictureId = 2,
                        Picture = new Picture
                        {
                            Url = "url"
                        }
                    }
                }
            };

            string sql = @"INSERT INTO Categories(Name, Description, Created, LastModified)
                           VALUES(@Name, @Description, @Created, @LastModified)";

            await conn.ExecuteAsync(sql, new
            {
                category.Name,
                category.Description,
                category.Created,
                category.LastModified
            });

            string catPicInsert = @"INSERT INTO CategoryPictures(fk_CategoryId, fk_PictureId)
                           VALUES(@CategoryId, @PictureId)";

            await conn.ExecuteAsync(catPicInsert, category.CategoryPictures);

            string PicInsert = @"INSERT INTO Pictures(Url)
                           VALUES(@Url)";

            await conn.ExecuteAsync(PicInsert, category.CategoryPictures.Select(x => 
                                                                              x.Picture).ToList());

它不会非常慢,但也不会像批量拷贝那么快。选项,假设SQL Server:

  • 可以将TVPs与Dapper一起使用,但唯一方便的方法是将输入数据打包到
    数据表中
    ;在Dapper repo中有使用TVP的例子,或者我可以删掉一个,但是它们很不方便,因为您需要在服务器上声明参数类型
  • 您可以使用
    SqlBulkCopy
    独立于Dapper将数据放入数据库;FastMember具有
    ObjectReader
    ,可以在键入的序列上构造
    IDataReader
    ,适合与
    SqlBulkCopy

如果不使用SQL Server,则需要查看RDBMS的特定于供应商的选项。

我已将其更改为对每个表使用多个存储过程

    public async Task<bool> CreateCategoryAsync(Category category)
    {
        category = new Category
        {
            Name = "category",
            Description = "description",
            Created = null,
            LastModified = null,
            CategoryPictures = new CategoryPicture[]
              {
                    new CategoryPicture
                    {
                        CategoryId = 1,
                        PictureId = 2,
                        Picture = new Picture
                        {
                            Url = "newUrl"
                        }
                    },
                      new CategoryPicture
                    {
                        CategoryId = 2,
                        PictureId = 2,
                        Picture = new Picture
                        {
                            Url = "url"
                        }
                    }
              }
        };

        string sql = @"EXEC Categories_Insert @Categories; 
                       EXEC CategoryPictures_Insert @CategoryPictures; 
                       EXEC Pictures_Insert @Pictures";


        var spParams = new DynamicParameters(new
        {
            Categories = category.ToDataTable().AsTableValuedParameter("CategoriesType"),

            CategoryPictures = category.CategoryPictures.ListToDataTable()
                                                        .AsTableValuedParameter("CategoryPictureType"),

            Pictures = category.CategoryPictures.Select(x => x.Picture)
                                                        .ListToDataTable()
                                                        .AsTableValuedParameter("PicturesType")
        });

        using (var conn = SqlConnection())
        {
            using (var res = await conn.QueryMultipleAsync(sql, spParams))
            {
                return true;
            }
        }
    }
公共异步任务CreateCategoryAsync(类别)
{
类别=新类别
{
Name=“category”,
Description=“Description”,
Created=null,
LastModified=null,
CategoryPictures=新的CategoryPicture[]
{
新类别结构
{
类别ID=1,
PictureId=2,
图片=新图片
{
Url=“newUrl”
}
},
新类别结构
{
类别ID=2,
PictureId=2,
图片=新图片
{
Url=“Url”
}
}
}
};
字符串sql=@“EXEC Categories_Insert@Categories;
EXEC CategoryPictures_Insert@CategoryPictures;
EXEC Pictures_Insert@Pictures”;
var spParams=新的动态参数(新的
{
Categories=category.ToDataTable().AsTableValuedParameter(“CategoriesType”),
CategoryPictures=category.CategoryPictures.ListToDataTable()
.AsTableValuedParameter(“类别类型”),
Pictures=category.CategoryPictures.Select(x=>x.Picture)
.ListToDataTable()
.AsTableValuedParameter(“图片类型”)
});
使用(var conn=SqlConnection())
{
使用(var res=await conn.QueryMultipleAsync(sql,spParams))
{
返回true;
}
}
}
这是我为将对象或对象列表映射到Datatable而创建的带有泛型方法的扩展类

public static class DataTableExtensions
{

    /// <summary>
    /// Convert an IEnumerable into a Datatable
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="listToDataTable"></param>
    /// <returns></returns>
    public static DataTable ListToDataTable<T>(this IEnumerable<T> listToDataTable)
    {
        DataTable dataTable = new DataTable();

        AddToDataTableColumns<T>(dataTable);

        foreach (var item in listToDataTable)
        {
            AddDataTableRows(dataTable, item);

        }

        return dataTable;
    }

    /// <summary>
    /// Comvert a Type of Class to DataTable
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static DataTable ToDataTable<T>(this T obj) where T : class
    {
        DataTable dataTable = new DataTable();

        AddToDataTableColumns<T>(dataTable);

        AddDataTableRows(dataTable, obj);

        return dataTable;
    }

    /// <summary>
    /// Add values from of Type T to a given Datatable columns
    /// </summary>
    /// <typeparam name="T">Extract values from</typeparam>
    /// <param name="dataTable">The datatable to add column values into</param>
    /// <returns></returns>
    private static DataTable AddToDataTableColumns<T>(DataTable dataTable)
    {
        try
        {
            PropertyInfo[] FilteredProps = GetFilteredProperties(typeof(T));

            for (int i = 0; i < FilteredProps.Length; i++)
            {
                PropertyInfo prop = FilteredProps[i];
                Type type = prop.PropertyType;

                dataTable.Columns.Add(prop.Name, Nullable.GetUnderlyingType(type) ?? type);
            }
        }
        catch (Exception ex)
        {
            new InfrastructuredException(ex.StackTrace);
        }

        return dataTable;
    }

    /// <summary>
    /// Add values from of Type T to a given Datatable Rows
    /// </summary>
    /// <typeparam name="T">Extract values from</typeparam>
    /// <param name="dataTable">The datatable to add Row values into</param>
    /// <returns></returns>
    private static DataTable AddDataTableRows<T>(DataTable dataTable, T obj)
    {
        try
        {
            PropertyInfo[] FilteredProps = GetFilteredProperties(typeof(T));

            object[] values = new object[FilteredProps.Length];

            for (int i = 0; i < values.Length; i++)
            {
                values[i] = FilteredProps[i].GetValue(obj);
            }
            dataTable.Rows.Add(values);
        }
        catch (Exception ex)
        {
            new InfrastructuredException(ex.StackTrace);
        }


        return dataTable;
    }


    /// <summary>
    /// Return an array of Filterered Properties of a Type
    /// </summary>
    /// <param name="type"></param>
    /// <returns>Properties that are filtered by Type</returns>
    private static PropertyInfo[] GetFilteredProperties(Type type)
    {
        return type.GetProperties()
                    .Where(p => p.Name != "Id" && !p.PropertyType.IsSubclassOf(typeof(BaseEntity)) && !p.PropertyType.IsInterface)
                    .ToArray();
    }

}
公共静态类DataTableExtensions
{
/// 
///将IEnumerable转换为Datatable
/// 
/// 
/// 
/// 
公共静态数据表ListToDataTable(此IEnumerable ListToDataTable)
{
DataTable=新的DataTable();
AddToDataTableColumns(dataTable);
foreach(listToDataTable中的变量项)
{
AddDataTableRows(数据表,项);
}
返回数据表;
}
/// 
///将类的类型转换为DataTable
/// 
/// 
/// 
/// 
公共静态数据表ToDataTable(此T对象),其中T:class
{
DataTable=新的DataTable();
AddToDataTableColumns(dataTable);
AddDataTableRows(dataTable,obj);
返回数据表;
}
/// 
///将T类型的值添加到给定的Datatable列
/// 
///从中提取值
///要向其中添加列值的datatable
/// 
专用静态DataTable AddToDataTableColumns(DataTable DataTable)
{
尝试
{
PropertyInfo[]FilteredProperties=GetFilteredProperties(类型为(T));
for(int i=0;ip.Name!=“Id”&&&!p.PropertyType.IsSubclassOf(typeof(BaseEntity))&&&!p.PropertyType.IsInterface)
.ToArray();
}
}