C# 转换IEnumerable的最佳方法<;T>;到Datatable进行SQL批量复制

C# 转换IEnumerable的最佳方法<;T>;到Datatable进行SQL批量复制,c#,sql,C#,Sql,我有一个模型和一个实例列表(大约5000个),需要复制到数据库中 我试图将我的对象同化到数据表中,但我不知道如何做到: public class BookingType { public int ID { get; set; } public string Name { get; set; } public decimal Price { get; set; } public int RandomProperty { get; set; } public

我有一个模型和一个实例列表(大约5000个),需要复制到数据库中

我试图将我的对象同化到数据表中,但我不知道如何做到:

public class BookingType {

    public int ID { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int RandomProperty { get; set; }
    public int RandomProperty2 { get; set; }

}

public void InsertSomeStuff(IEnumerable<BookingType> bookings) {
    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString)) {
        conn.Open();

        DataTable dt = new DataTable();

        using (SqlBulkCopy copy = new SqlBulkCopy(conn)) {
            copy.ColumnMappings.Add(0, 1);

            copy.DestinationTableName = "dbo.Bookings";
            copy.WriteToServer(dt);
        }
    }
}
公共类BookingType{
公共int ID{get;set;}
公共字符串名称{get;set;}
公共十进制价格{get;set;}
公共属性{get;set;}
公共int RandomProperty2{get;set;}
}
public void InsertSomeStuff(IEnumerable预订){
使用(SqlConnection conn=new SqlConnection(ConfigurationManager.ConnectionString[“DefaultConnection”].ConnectionString)){
conn.Open();
DataTable dt=新的DataTable();
使用(SqlBulkCopy复制=新SqlBulkCopy(conn)){
copy.ColumnMappings.Add(0,1);
copy.DestinationTableName=“dbo.Bookings”;
copy.WriteToServer(dt);
}
}
}

我如何做到这一点?

您正在使用linq to sql吗?在这种情况下,这种方法非常好:

部分类MyDataContext
{
部分void OnCreated()
{
CommandTimeout=5*60;
}
公共void BulkInsertAll(IEnumerable实体)
{
entities=entities.ToArray();
字符串cs=Connection.ConnectionString;
var conn=新的SqlConnection(cs);
conn.Open();
类型t=类型(t);
var tableAttribute=(tableAttribute)t.GetCustomAttributes(
typeof(TableAttribute),false.Single();
var bulkCopy=new SqlBulkCopy(conn){
DestinationTableName=tableAttribute.Name};
var properties=t.GetProperties().Where(EventTypeFilter.ToArray();
var table=新数据表();
foreach(属性中的var属性)
{
类型propertyType=property.propertyType;
如果(propertyType.IsGenericType&&
propertyType.GetGenericTypeDefinition()==typeof(可为null))
{
propertyType=Nullable.GetUnderlyingType(propertyType);
}
table.Columns.Add(新数据列(property.Name,propertyType));
}
foreach(实体中的var实体)
{
table.Rows.Add(properties.Select(
property=>GetPropertyValue(
.GetValue(实体,null)).ToArray();
}
bulkCopy.WriteToServer(表);
康涅狄格州关闭();
}
私有bool EventTypeFilter(System.Reflection.PropertyInfo p)
{
var attribute=attribute.GetCustomAttribute(p,
(AssociationAttribute)的类型作为AssociationAttribute;
if(attribute==null)返回true;
如果(attribute.IsForeignKey==false)返回true;
返回false;
}
私有对象GetPropertyValue(对象o)
{
如果(o==null)
返回DBNull.Value;
返回o;
}
}

您是否使用linq to sql?在这种情况下,这种方法非常好:

部分类MyDataContext
{
部分void OnCreated()
{
CommandTimeout=5*60;
}
公共void BulkInsertAll(IEnumerable实体)
{
entities=entities.ToArray();
字符串cs=Connection.ConnectionString;
var conn=新的SqlConnection(cs);
conn.Open();
类型t=类型(t);
var tableAttribute=(tableAttribute)t.GetCustomAttributes(
typeof(TableAttribute),false.Single();
var bulkCopy=new SqlBulkCopy(conn){
DestinationTableName=tableAttribute.Name};
var properties=t.GetProperties().Where(EventTypeFilter.ToArray();
var table=新数据表();
foreach(属性中的var属性)
{
类型propertyType=property.propertyType;
如果(propertyType.IsGenericType&&
propertyType.GetGenericTypeDefinition()==typeof(可为null))
{
propertyType=Nullable.GetUnderlyingType(propertyType);
}
table.Columns.Add(新数据列(property.Name,propertyType));
}
foreach(实体中的var实体)
{
table.Rows.Add(properties.Select(
property=>GetPropertyValue(
.GetValue(实体,null)).ToArray();
}
bulkCopy.WriteToServer(表);
康涅狄格州关闭();
}
私有bool EventTypeFilter(System.Reflection.PropertyInfo p)
{
var attribute=attribute.GetCustomAttribute(p,
(AssociationAttribute)的类型作为AssociationAttribute;
if(attribute==null)返回true;
如果(attribute.IsForeignKey==false)返回true;
返回false;
}
私有对象GetPropertyValue(对象o)
{
如果(o==null)
返回DBNull.Value;
返回o;
}
}

您可以使用通用方法创建任意类型的
IEnumerable
数据表。我们如何将其标记为不重复?您可以使用通用方法创建任意类型的
IEnumerable
数据表。我们如何将其标记为不重复?这将以与相同的性能运行我的答案中有大量的SQL语句??(是的,我正在使用L2S)我相信代码是有效的,但我得到了:数据源中给定的DateTime类型值无法转换为指定目标列的int类型。我猜您正在使用一些特殊的列映射,但是如果不知道类是如何映射到sql的,就很难判断。你完全正确,除非有一点,models属性顺序必须与databases列顺序相匹配。我的问题和更相关的答案的奇妙推断比它被标记为一个复制品。谢谢:)我在一些字段中添加了[NotMapping]。然后我更改了这一行t.GetProperties(),其中(p=>!Attribute.IsDefined(p,typeof(NotMappedAttribute))&(p.PropertyType.IsValueType | | p.PropertyType==typeof(string));这会在最后一刻运行吗
partial class MyDataContext
{
    partial void OnCreated()
    {
        CommandTimeout = 5 * 60;
    }

    public void BulkInsertAll<T>(IEnumerable<T> entities)
    {
        entities = entities.ToArray();

        string cs = Connection.ConnectionString;
        var conn = new SqlConnection(cs);
        conn.Open();

        Type t = typeof(T);

        var tableAttribute = (TableAttribute)t.GetCustomAttributes(
            typeof(TableAttribute), false).Single();
        var bulkCopy = new SqlBulkCopy(conn) { 
            DestinationTableName = tableAttribute.Name };

        var properties = t.GetProperties().Where(EventTypeFilter).ToArray();
        var table = new DataTable();

        foreach (var property in properties)
        {
            Type propertyType = property.PropertyType;
            if (propertyType.IsGenericType &&
                propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                propertyType = Nullable.GetUnderlyingType(propertyType);
            }

            table.Columns.Add(new DataColumn(property.Name, propertyType));
        }

        foreach (var entity in entities)
        {
            table.Rows.Add(properties.Select(
              property => GetPropertyValue(
              property.GetValue(entity, null))).ToArray());
        }

        bulkCopy.WriteToServer(table);
        conn.Close();
    }

    private bool EventTypeFilter(System.Reflection.PropertyInfo p)
    {
        var attribute = Attribute.GetCustomAttribute(p, 
            typeof (AssociationAttribute)) as AssociationAttribute;

        if (attribute == null) return true;
        if (attribute.IsForeignKey == false) return true; 

        return false;
    }

    private object GetPropertyValue(object o)
    {
        if (o == null)
            return DBNull.Value;
        return o;
    }
}