2017-01-13 3 views
2

Ich habe eine gleichzeitige Warteschlange mit einem Klassenobjekt definiert, wie untenSqlBulkCopy mit gleichzeitiger Warteschlange

ConcurrentQueue<Data> DataQueue = new ConcurrentQueue<Data>(); 

public class Data 
{ 
    public string Id { get; set; } 
    public string T { get; set; } 
    public string D { get; set; } 
    public string L { get; set; } 
    public string I { get; set; } 
    public string V { get; set; } 
} 

Ich verwende folgenden Code einzufügen in

db definiert 65000 Aufzeichnungen hält
public void InsertIntoDB() 
    { 

     using (cn = new SqlConnection(connectionString)) 
     { 
      cn.Open(); 

      Data item; 
      while (SpotDataQueue.Count > 0) 
      { 
       if (DataQueue.TryDequeue(out item)) 
       { 
        using (SqlCommand cm = cn.CreateCommand()) 
        { 
         cm.CommandText = @"INSERT INTO [TableName] ([WId], [L], [I], [V],[JId],[I],[DateTime]) VALUES (@WId, @l, @i, @v, @jid,@i,@dt)"; 
         cm.Parameters.AddWithValue("WId", item.Id); 
         cm.Parameters.AddWithValue("@l", item.L); 
         cm.Parameters.AddWithValue("@i", item.I); 
         cm.Parameters.AddWithValue("@v", item.V); 
         cm.Parameters.AddWithValue("@jid", 1); 
         cm.Parameters.AddWithValue("@i", false); 
         cm.Parameters.AddWithValue("@dt", DateTime.Now); 
         cm.ExecuteNonQuery(); 
        } 
       } 
      } 
     } 
    } 

Tabellenstruktur:

WId   nvarchar(50) AllowNulls 
L   nvarchar(MAX) AllowNulls 
I   nvarchar(MAX) AllowNulls 
V   nvarchar(MAX) AllowNulls 
JId   int    AllowNulls 
I   bit    AllowNulls 
DateTime datetime  AllowNulls 

Wie meine gleichzeitige Warteschlange vom Typ Daten zu einer Datatable oder Datareader konvertieren SQLBULKCOPY möglich machen?

Danke.

+0

Ich wäre vorsichtig mit Wenn Sie Ihre 'InsertIntoDB'-Funktion schneller einfügen als Sie in die concurrentQueue schreiben, wird Ihre' while'-Schleife beendet und neue Daten werden später hinzugefügt. Betrachten sie die Umstellung auf einen 'neuen Blocking (neu ConcurrentQueue ())' und mit 'foreach (Datenelement in SpotDataQueue.GetConsumingEnumerable()' statt) der while-Schleife und die 'TryDequeue' –

+0

@ScottChamberlain: Hallo, ist Warteschlange bereits geladen mit 65000 Datensätzen, so dass das Problem in diesem Szenario nicht hier ist. Ich werde Ihren Vorschlag auch in Betracht ziehen. Danke :) –

Antwort

3

Here ist ein Verfahren, das die Arbeit mit Hilfe der Reflexion bedeutet (geändert Parametertyp):

public static DataTable ToDataTable<T>(this IEnumerable<T> items) 
{ 
    var tb = new DataTable(typeof(T).Name); 

    PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); 

    foreach(var prop in props) 
    { 
     tb.Columns.Add(prop.Name, prop.PropertyType); 
    } 

    foreach (var item in items) 
    { 
     var values = new object[props.Length]; 
     for (var i=0; i<props.Length; i++) 
     { 
      values[i] = props[i].GetValue(item, null); 
     } 

     tb.Rows.Add(values); 
    } 

    return tb; 
} 

Jetzt können Sie es mit Ihrem Queue:

DataTable dataSourceForSqlBulkCopy = DataQueue.ToDataTable(); 
+0

Hallo, danke für die Antwort, ich werde das versuchen und Sie wissen lassen :) –

+0

Hallo, Vielen Dank, Es funktioniert :) –