C# 转换IEnumerable的最佳方法<;T>;到Datatable进行SQL批量复制
我有一个模型和一个实例列表(大约5000个),需要复制到数据库中 我试图将我的对象同化到数据表中,但我不知道如何做到: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
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;
}
}