speed up data import to sql from windows forms - sql-server

I've made a windows forms app that imports data to my sql database.
This is how data can look in the database
Problem If I now want to import more data and say that there is a entry in the new data that I'm importing that already exist in my sql data table, that is, an entry with the exact same value that already exist in my sql table. Then I would like to not import this particular entry and move on the next one.
The code I'm using for this is paintstakingly slow and I would like to find a quicker/better way of doing this. Please see #region DAX for the code and the try catch.
Here is the code that executes on my button click for import :)
Thanks!
private void dataImportButton_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
int candle = 0;
string candleStick = "";
foreach (var item in checkedListBox1.CheckedItems)
{
candleStick += item.ToString();
}
Regex regex = new Regex(#"\d*");
Match match = regex.Match(candleStick);
if (match.Success)
{
candle = Convert.ToInt32(match.Value);
}
string nameOfTable = string.Empty;
foreach (var item in checkedListBox2.CheckedItems)
{
nameOfTable += item.ToString();
}
string filePath = textBox1.Text;
var listaNerladdat = System.IO.File.ReadLines(filePath);
if (nameOfTable == "DAX")
#region DAX
{
foreach (var item in listaNerladdat)
{
var splitLista = item.Split(';').ToList();
if (splitLista.Count < 5)
continue;
var tmpSplitInfo = new DaxSuperTabell();
DateTime tmpDate;
if (DateTime.TryParse(splitLista[0], out tmpDate))
tmpSplitInfo.TimeStampMVCR = tmpDate;
double tmpX;
if (Double.TryParse(splitLista[1].Replace('.', ','), out tmpX))
tmpSplitInfo.HighPriceMVCR = tmpX;
if (Double.TryParse(splitLista[2].Replace('.', ','), out tmpX))
tmpSplitInfo.LowPriceMVCR = tmpX;
if (Double.TryParse(splitLista[3].Replace('.', ','), out tmpX))
tmpSplitInfo.OpenPriceMVCR = tmpX;
if (Double.TryParse(splitLista[4].Replace('.', ','), out tmpX))
tmpSplitInfo.ClosePriceMVCR = tmpX;
tmpSplitInfo.CandleStick = candle;
try{
_context.DaxSuperTabell.AddRange(tmpSplitInfo);
_context.SaveChanges();
}
catch{MessageBox.Show("This entry is a double")}
}
}
#endregion
}

Related

How can I save items to SQL Server?

I have a site that can upload three pictures, that page saves some other data in the table in SQL Server, but it saves the name of one the pictures the same for pictures in database.
Of course, the name of the pictures are different in the folder that save.
My code:
foreach (var item in FileUpload)
{
if (item != null)
{
Random rnd = new Random();
string Pic = rnd.Next().ToString() + ".jpg";
// string Pic = System.IO.Path.GetFileName(file.FileName);
string Path = System.IO.Path.Combine(Server.MapPath("~/images/cover/"));
item.SaveAs(Path + Pic);
using (MemoryStream ms = new MemoryStream())
{
item.InputStream.CopyTo(ms);
byte[] array = ms.GetBuffer();
}
lstName.Add(Pic);
}
}
else
{
lstName.Add("9.jpg");
}
RContact.InsertContact(t, lstNam);
ViewBag.Style = "color:green;";
}
and I write in the Repository:
public bool InsertContact(tbl_contact t, List<string> PicsName)
{
db.tbl_contact.Add(t);
foreach (var item in PicsName)
{
t.picname = PicsName[0];
t.picnamet = PicsName[1];
t.picnametr = PicsName[2];
db.tbl_contact.Add(t);
}
return Convert.ToBoolean(db.SaveChanges());
}
but it save the same name.

delay while opening view in wpf application

We are developing application using WPF,material design and MS-Access 2007 as Back End. Now we are facing problem of application slow down while opening single view ,that particular view have 16 combo's which fill. It take 7 seconds for process, following code used for bind combo box item source
List<ComboBind> values = new List<ComboBind>();
try
{
using (var oleDbCommand = new OleDbCommand())
{
oleDbCommand.CommandText = query ;
oleDbCommand.Connection = Connection.con;
var sql = query;
var oleDbDataReader = oleDbCommand.ExecuteReader();
while (oleDbDataReader.Read())
{
ComboBind b = new ComboBind();
b.id = oleDbDataReader[0].ToString().ToInt();
b.name = oleDbDataReader[1].ToString();
values.Add(b);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
It looks like you are trying to load data in UI thread during view initialization and this is the reason of the issue. Either do loading of data in background thread or do it before opening the view.
Simple code snippet for loading data in separate task:
//Might be your view code behind or
//ViewModel if you are using MVVM
public class ViewCodeBehind
{
public List<ComboBind> ComboItems { get; set; }
public void Initialize()
{
//start bacground task for data loading
var comboQuery = "select *from data";
Task.Run(() => LoadItems(comboQuery));
}
public void LoadItems(string query)
{
List<ComboBind> values = new List<ComboBind>();
try
{
using (var oleDbCommand = new OleDbCommand())
{
oleDbCommand.CommandText = query;
oleDbCommand.Connection = Connection.con;
var sql = query;
var oleDbDataReader = oleDbCommand.ExecuteReader();
while (oleDbDataReader.Read())
{
ComboBind b = new ComboBind();
b.id = oleDbDataReader[0].ToString().ToInt();
b.name = oleDbDataReader[1].ToString();
values.Add(b);
}
}
//use dispatcher to pass data back to UI thread
System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(
new Action(() =>
{
ComboItems = values;
}));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}

DevExpress DisplayFormat in RowCellStyle

Switching application to use DevExpress XtraGrid and implemented customized color and format for row/cells.
For most part formats are being applied correctly. However when applied to a decimal 1000 following format "#,###;(#,###);0" ends up 1000.0000 instead of 1,000.
gridView.RowCellStyle += CellFormatting;
private void CellFormatting(object sender, RowCellStyleEventArgs e)
{
if (gridView.IsRowSelected(e.RowHandle))
{
e.Appearance.BackColor = SystemColors.Highlight;
e.Appearance.ForeColor = SystemColors.HighlightText;
return;
}
// get cell by its index
var gridRow = gridView.GetRow(e.RowHandle);
TLColumn columnEnum = ((BindableTextBoxColumn)e.Column).ColumnEnum;
// get new format values
T row = (T)gridRow;
e.Column.DisplayFormat.FormatString = row.GetCellFormat(columnEnum);
e.Appearance.BackColor = row.GetCellBackColor(columnEnum);
e.Appearance.ForeColor = row.GetCellColor(columnEnum);
}
For bound columns that do not use CustomColumnDisplayText need to set FormatType before setting DisplayFormatString.
e.Column.ColumnType
can show type of the bound property
private void CellFormatting(object sender, RowCellStyleEventArgs e)
{
// get cell by its index
var gridRow = gridView.GetRow(e.RowHandle);
var column = (BindableTextBoxColumn)e.Column;
TLColumn columnEnum = column.ColumnEnum;
// get new format values
T row = (T)gridRow;
e.Column.DisplayFormat.FormatType = (column.IsNumeric) ? FormatType.Numeric : column.DisplayFormat.FormatType;
e.Column.DisplayFormat.FormatString = row.GetCellFormat(columnEnum);
if (gridView.IsRowSelected(e.RowHandle))
{
e.Appearance.BackColor = SystemColors.Highlight;
e.Appearance.ForeColor = SystemColors.HighlightText;
return;
}
e.Appearance.BackColor = row.GetCellBackColor(columnEnum);
e.Appearance.ForeColor = row.GetCellColor(columnEnum);
}

How to parallelize 3d model creation?

Bit of a special case here, because I'm using a library called helix-toolkit but bear with me.
The thing is I would like to parallelize the creation of model objects in my code using a backgroundworker.
I know that there is a big issue with mutlithreading and working on UI elements but maybe somehow there is a workaround.
Here is the rough structure of my code:
First file in which I create the Backgroundwoker, splitting the workload for creating Geometry3D objects and finally calling SetModelGeometry to bind the geometries to the viewport. The second file shows how the binding is done.
MainWindow.xaml.cs
private void Draw_Building()
{
_worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true };
_worker.DoWork += Draw_Building_DoWork;
_worker.ProgressChanged += DrawBuilding_ProgressChanged;
_worker.RunWorkerCompleted += DrawBuilding_RunWorkerCompleted;
_worker.RunWorkerAsync(10000);
}
private void Draw_Building_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
// returns a list containing Geometry3D objects ( created by meshBuilder.ToMeshGeometry3D() )
Geometryhandler.Draw_Building(sender, e);
}
private void DrawBuilding_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
StatusProgressBar.Value = e.ProgressPercentage;
var i = (int)e.UserState;
var actualComponent = MyBuildingComponents.First(c => c.Id == i);
LblStatusbarInfo.Text = "Currently meshing element #" + actualComponent.Globalid + " (" +
actualComponent.Objectname + ")";
StatusProgressbarMsg.Text = "Meshing (" + e.ProgressPercentage + " %)";
}
private void DrawBuilding_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
StatusProgressbarMsg.Text = "-";
StatusProgressBar.Value = 0;
LblStatusbarInfo.Text = "Meshing completed.";
Geometry = e.Result as List<MeshIdandGeometry>;
// creates MeshGeometryModel3D objects and binds them to the viewport using the List of Geometries
MainViewModel.SetModelGeometry(Geometry);
}
MainViewModel.cs
public void SetModelGeometry(List<MeshIdandGeometry> geometry)
{
MyModelGeometry = new Element3DCollection();
if (geometry != null)
{
foreach (var mygeometry in geometry)
{
var s = new MeshGeometryModel3D
{
Geometry = mygeometry.Geometry,
Material = mygeometry.Material,
};
this.MyModelGeometry.Add(s);
s.Attach(MyModelViewport.RenderHost);
}
}
this.OnPropertyChanged("MyModelGeometry");
}
My problem at the moment is the following error message:
The calling thread cannot access this object because a different
thread owns it.
which is thrown in the SetModelGeometry function when trying to attach the ModelGeometry to the viewport.
I guess the compiler is complaining about the fact that the geometries were created in different threads, to which he has no access now.
Is there any workaround/solution without destroying the parallel execution of the DrawBuilding function?
EDIT:
EDIT 2: posted the wrong version of the Draw_Building method
The Draw_Building method in the Geometryhandler:
public void Draw_Building(object sender, DoWorkEventArgs e)
{
var geometry = new List<MeshIdandGeometry>();
var standardMaterial = new PhongMaterial()
{
AmbientColor = SharpDX.Color.LightGray,
//DiffuseColor = new Color4(0.35f, 0.35f, 0.35f, 1.0f),
//DiffuseMap = new BitmapImage(new System.Uri(#"Con_Diffuse_2.jpg", System.UriKind.RelativeOrAbsolute)),
//NormalMap = new BitmapImage(new System.Uri(#"Con_Normal_2.jpg", System.UriKind.RelativeOrAbsolute)),
};
var max = _mainWindow.MyBuildingComponents.Count;
var i = 1;
// Loop over building components
foreach (var component in _mainWindow.MyBuildingComponents)
{
//if (i == 5) break;
var component1 = component;
var componentTriangles = _mainWindow.MyTriangles.Where(triangle => triangle.ComponentId == component1.Id);
var meshBuilder = new MeshBuilder(true, true, true);
// Loop over triangles in building element
foreach (var triangle in componentTriangles)
{
var triangle1 = triangle;
var p1 = _mainWindow.MyVertices.Find(
vt => vt.Id == triangle1.PointId1);
var p2 = _mainWindow.MyVertices.Find(
vt => vt.Id == triangle1.PointId2);
var p3 = _mainWindow.MyVertices.Find(
vt => vt.Id == triangle1.PointId3);
if (p1 != null && p2 != null && p3 != null)
{
//meshBuilder.AddTriangle(new Vector3((float)p1.X, (float)p1.Y, (float)p1.Z),
// new Vector3((float)p2.X, (float)p2.Y, (float)p2.Z),
// new Vector3((float)p3.X, (float)p3.Y, (float)p3.Z));
// coordination are switched to match the coordinate system in SharpDX viewport
meshBuilder.AddTriangle(new Vector3(-(float)p1.Y, (float)p1.Z, -(float)p1.X),
new Vector3(-(float)p2.Y, (float)p2.Z, -(float)p2.X),
new Vector3(-(float)p3.Y, (float)p3.Z, -(float)p3.X));
}
}
var mesh = meshBuilder.ToMeshGeometry3D();
var meshandtriangle = new MeshIdandGeometry
{
Id = component1.Id,
Geometry = mesh,
Material = standardMaterial,
};
geometry.Add(meshandtriangle);
i++;
var progressPercentage = Convert.ToInt32(((double)i / max) * 100);
var backgroundWorker = sender as BackgroundWorker;
backgroundWorker?.ReportProgress(progressPercentage, component1.Id);
}
e.Result = geometry;
}
Big thanks to #egse for finding a solution.
Part of the code that causes the problem:
var standardMaterial = new PhongMaterial()
{
AmbientColor = SharpDX.Color.LightGray,
//DiffuseColor = new Color4(0.35f, 0.35f, 0.35f, 1.0f),
//DiffuseMap = new BitmapImage(new System.Uri(#"Con_Diffuse_2.jpg", System.UriKind.RelativeOrAbsolute)),
//NormalMap = new BitmapImage(new System.Uri(#"Con_Normal_2.jpg", System.UriKind.RelativeOrAbsolute)),
};
Basically the problem with the above code is that the material is created as a local variable inside the scope of the backgroundworker. This causes problems with ownership when the UI thread tries to enter the material objects.
The solution to this problem is to make sure that the material is created by the UI thread (e.g in this case, the constructor of the Geometryhandler)
TL;DR: Do not create instances of classes which inherit from DependencyObject in another thread than the UI.

Is there a utility to dump an existing log4j log file into a relational database?

Seems, like a very basic thing, but I could not find it.
I have a bunch of log4j/log4net log files. I would like to dump them into a database in order to be able to analyze them with ease.
I thought I would find a tool to do it in no time, apparently I am wrong.
Does anyone know of such a tool?
OK, so I found no utility. Had to write my own. Of course, it is strictly tailored to my immediate needs (time is money), however, it can save you a bit of time to start your own, in case of a need. Here is the complete code in C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
namespace ConsoleApplication3
{
class Program
{
public class LogEntry
{
private const string PATTERN = #"^(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d\.\d{4}) (\S+) \[(\d+)\] (\w+) (\S+) - (.*)$";
private static readonly Regex s_regex = new Regex(PATTERN, RegexOptions.Compiled);
public DateTime TS;
public string Machine;
public int Thread;
public string Level;
public string Logger;
public string Message;
public static LogEntry TryCreate(string line)
{
var match = s_regex.Match(line);
return match.Success ? new LogEntry
{
TS = DateTime.ParseExact(match.Groups[1].Value, "yyyy-MM-dd HH:mm:ss.ffff", CultureInfo.InvariantCulture),
Machine = match.Groups[2].Value,
Thread = int.Parse(match.Groups[3].Value),
Level = match.Groups[4].Value,
Logger = match.Groups[5].Value,
Message = match.Groups[6].Value,
} : null;
}
public void AppendToMessage(string line)
{
Message += Environment.NewLine + line;
}
}
static void Main()
{
const string SQL = #"
INSERT INTO log ( ts, machine, thread, level, logger, message, journalId)
VALUES (#ts, #machine, #thread, #level, #logger, #message, #journalId)
";
using (var connection = new SqlConnection("server=localhost;database=misc;uid=SantaClaus;pwd=MerryChristmas"))
{
connection.Open();
using (var command = new SqlCommand(SQL, connection))
{
var tsParam = new SqlParameter("#ts", SqlDbType.DateTime);
var machineParam = new SqlParameter("#machine", SqlDbType.NVarChar, 32);
var threadParam = new SqlParameter("#thread", SqlDbType.Int);
var levelParam = new SqlParameter("#level", SqlDbType.NVarChar, 10);
var loggerParam = new SqlParameter("#logger", SqlDbType.NVarChar, 128);
var messageParam = new SqlParameter("#message", SqlDbType.NVarChar, -1);
var journalIdParam = new SqlParameter("#journalId", SqlDbType.Int);
command.Parameters.Add(tsParam);
command.Parameters.Add(machineParam);
command.Parameters.Add(threadParam);
command.Parameters.Add(levelParam);
command.Parameters.Add(loggerParam);
command.Parameters.Add(messageParam);
command.Parameters.Add(journalIdParam);
// Call Prepare after setting the Commandtext and Parameters.
command.Prepare();
int i = 0;
foreach (var file in Directory.GetFiles(#"c:\tmp\dfbje01"))
{
journalIdParam.Value = OpenJournal(connection, file);
command.Transaction = connection.BeginTransaction();
foreach (var e in GetLogEntries(file))
{
tsParam.Value = e.TS;
machineParam.Value = e.Machine;
threadParam.Value = e.Thread;
levelParam.Value = e.Level;
loggerParam.Value = e.Logger;
messageParam.Value = e.Message;
command.ExecuteNonQuery();
++i;
if (i == 1000)
{
i = 0;
command.Transaction.Commit();
command.Transaction = connection.BeginTransaction();
}
}
command.Transaction.Commit();
CloseJournal(connection, journalIdParam.Value);
}
}
}
}
private static void CloseJournal(SqlConnection connection, object id)
{
const string SQL = "UPDATE journal SET done = 1 WHERE id = #id";
using (var command = new SqlCommand(SQL, connection))
{
command.Parameters.Add(new SqlParameter("#id", id));
command.ExecuteNonQuery();
}
}
private static object OpenJournal(SqlConnection connection, string filePath)
{
const string SQL = "INSERT INTO journal (filePath) OUTPUT inserted.id VALUES (#filePath)";
using (var command = new SqlCommand(SQL, connection))
{
command.Parameters.Add(new SqlParameter("#filePath", filePath));
return command.ExecuteScalar();
}
}
private static IEnumerable<LogEntry> GetLogEntries(string filePath)
{
LogEntry prev = null;
foreach (var line in File.ReadLines(filePath))
{
var logEntry = LogEntry.TryCreate(line);
if (logEntry != null)
{
if (prev != null)
{
yield return prev;
}
prev = logEntry;
}
else if (prev != null)
{
prev.AppendToMessage(line);
}
else
{
// Oops
Console.WriteLine(line);
}
}
if (prev != null)
{
yield return prev;
}
}
}
}
Mind trying out the filtering, search, colorizing features of the latest developer snapshot of Chainsaw? It has a good number of features which may avoid the need to use a DB. If you use a VFSLogFilePatternReceiver, it can parse and tail any regular text file, including those created by log4net.
Latest developer snapshot of Chainsaw is available here:
http://people.apache.org/~sdeboy

Resources