Hi all i have written the following transaction to insert data but when i am getting an exception only the data which got the exception not inserting to db the remaining all are inserting
This is what i wrote
public bool addWhole(SqlTransaction osqlTrans)
{
m_flag = false;
osqlTrans = null;
SqlConnection osqlCon = new SqlConnection(constr);
if (osqlCon.State != ConnectionState.Open)
{
osqlCon.Open();
}
osqlTrans = osqlCon.BeginTransaction();
try
{
if (this.addRisk(osqlTrans, osqlCon))
{
if (this.addEconomical(osqlTrans, osqlCon))
{
osqlTrans.Commit();
}
}
}
catch (Exception ex)
{
osqlTrans.Rollback();
}
finally
{
osqlCon.Close();
}
return m_flag;
}
public bool addRisk(SqlTransaction oRiskTrans, SqlConnection oRiskConn)
{
con = new SqlConnection(constr);
if (con.State != ConnectionState.Open)
{
con.Open();
}
cmd = new SqlCommand("insert into tblEnrollmentData (EID,Eyear,Epercent) values('" + id + "','" + str + "','" + dbPercent + "')", con); //Even i tried adding transaction in command statement
if (cmd.ExecuteNonQuery() > 0)
{
m_flag = true;
}
}
public bool addEconomical(SqlTransaction oRiskTrans, SqlConnection oRiskConn)
{
con = new SqlConnection(constr);
if (con.State != ConnectionState.Open)
{
con.Open();
}
cmd = new SqlCommand("insert into tblEnrollmentData (EID,Eyear,Epercent) values('" + id + "','" + str + "','" + dbPercent + "')", con);//Even i tried adding transaction in command statement
if (cmd.ExecuteNonQuery() > 0)
{
m_flag = true;
}
}
I tried to rollback the transaction by failing the second condition but my first statement is inserting to DB.. What should i do in order to overcome this
I'm guessing its one of these things
1) You are not using the same connection object for all the different commands
2) You are not assigning the transaction to the commands before you execute them
3) Both perhaps
Try using the same connection object and assigning the transaction to the command before you execute it for an example see this page on MSDN. http://msdn.microsoft.com/en-us/library/86773566.aspx
Transaction is not shared between connections and you always create a new connection. Use oRiskConn specified as 2nd parameter of your methods.
As you are creating a new connection in every function your code didn't work. Just remove the connection
`con = new SqlConnection(constr);`
Replace it with the connection available in your function i.e
oRiskConn and don't initialize it as a new connection. If you did so again your transaction as per your requirement will not work. Also include oRiskTrans in your command object. Then it will works as per your requirement
I don't know what some of your parameters are but it looks like you want something like this:
class SomeClass
{
// These need to be set to appropriate values
int id, str;
double dbPercent;
string constr;
public bool addWhole()
{
var m_flag = false;
using (var osqlCon = new SqlConnection(constr))
{
if (osqlCon.State != ConnectionState.Open)
{
osqlCon.Open();
}
using (var osqlTrans = osqlCon.BeginTransaction())
{
try
{
if (m_flag = this.addRisk(osqlTrans))
{
if (m_flag = this.addEconomical(osqlTrans))
{
osqlTrans.Commit();
}
}
}
catch (Exception)
{
// Use $exception in watch window if you are debugging
osqlTrans.Rollback();
}
}
}
return m_flag;
}
public bool addRisk(SqlTransaction oRiskTrans)
{
var m_flag = false;
using (var cmd = new SqlCommand("insert into tblEnrollmentData (EID,Eyear,Epercent) values('" + id + "','" + str + "','" + dbPercent + "')"))
{
cmd.Transaction = oRiskTrans;
cmd.Connection = oRiskTrans.Connection;
if (cmd.ExecuteNonQuery() > 0)
{
m_flag = true;
}
}
return m_flag;
}
public bool addEconomical(SqlTransaction oRiskTrans)
{
var m_flag = false;
using (var cmd = new SqlCommand("insert into tblEnrollmentData (EID,Eyear,Epercent) values('" + id + "','" + str + "','" + dbPercent + "')"))
{
cmd.Transaction = oRiskTrans;
cmd.Connection = oRiskTrans.Connection;
if (cmd.ExecuteNonQuery() > 0)
{
m_flag = true;
}
}
return m_flag;
}
}
Related
I need to create the best architecture for my app to manage my different connections (two) and the stored procedure.
So far I have created one SQL class and do not handle the two connections : I have mixed methods and functions which can be called regardless of the connection (and can crash).
How do I create a Connection class and a DAL ?
My SQL connection class :
namespace GripPicture.Data
{
class Sqlmap
{
static string RmSynchro = "ConnectionRmSynchro";
static string PascomPhoto = "ConnectionPascomPhoto";
private string config;
private OleDbConnection _lConnection = new OleDbConnection();
private OleDbConnection OleConnection
{
get
{
if (_lConnection.State != ConnectionState.Open)
{
if (_lConnection.State != ConnectionState.Connecting)
{
_lConnection.OpenAsync();
}
}
return _lConnection;
}
set { _lConnection = value; }
}
public Sqlmap(bool pIsPascom = false)
{
config = pIsPascom ? ConfigurationManager.AppSettings[PascomPhoto] : ConfigurationManager.AppSettings[RmSynchro];
OleConnection = new OleDbConnection(config);
}
private void Connection()
{
OleConnection.OpenAsync();
}
public int ExcuteUpdate(string pQuery)
{
// Check if connection is closed
OleDbCommand command = new OleDbCommand(pQuery, OleConnection);
return command.ExecuteNonQuery();
}
// This function should reside in your SQL-class.
public IEnumerable<T> ExecuteQueryForList<T>(string pQuery)
{
List<T> items = new List<T>();
Type type = typeof(T);
var data = ExecuteDataTable(pQuery);
foreach (DataRow row in data.Rows)
{
// Object have a constructor with a Datarow
T item = (T)Activator.CreateInstance(typeof(T), row);
PascomPhotoDo element = (PascomPhotoDo)Activator.CreateInstance(typeof(PascomPhotoDo), row);
if ((items.Cast<PascomPhotoDo>()).Any((elem => elem.NumeroContact == element.NumeroContact)))
{
LogHelper.Log("Doublons dans la liste Id Pascom " + element.NumeroContact + " " + element.FirstName + " Atlas " + element.IdParticipantAtlas);
//Console.WriteLine("Doublon dans liste : " + element.NumeroContact + " " + element.FirstName + " Atlas " + element.IdParticipantAtlas);
}
items.Add(item);
}
return items;
}
private DataTable ExecuteDataTable(string pQuery)
{
OleDbDataAdapter dp1 = new OleDbDataAdapter(pQuery, OleConnection);
DataSet ldataSet = new DataSet();
dp1.Fill(ldataSet, "table");
return ldataSet.Tables[0];
}
#region PASCOM
public byte[] GetPictureFromPascom(int pNumeroContact)
{
byte[] lDataPicture = null;
OleDbCommand command = new OleDbCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "itsp_Photo_GetPhotoByContact";
command.Connection = OleConnection;
command.Parameters.Add("#numero_contact", OleDbType.Integer).Value = pNumeroContact;
command.CommandTimeout = 15000;
try
{
lDataPicture = (byte[])command.ExecuteScalar();
}
catch (Exception e)
{
LogHelper.Log("Fail to get picture \n" + " Id Pascom " + pNumeroContact + " " + e.Message);
}
return lDataPicture;
}
public void InsertPictureToDatabase(PascomPhotoDo pPascomPhoto)
{
OleDbCommand command = new OleDbCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "itsp_Photo_CreatePhotoContact";
command.Connection = OleConnection;
command.Parameters.Add("#idContact", OleDbType.Integer).Value = pPascomPhoto.NumeroContact;
command.Parameters.Add("#photo", OleDbType.Binary).Value = pPascomPhoto.PhotoByteReduced;
command.Parameters.Add("#source", OleDbType.VarChar).Value = "blabla";
command.Parameters.Add("#idSalonOrganise", OleDbType.VarChar).Value = "blabla";
command.Parameters.Add("#IdParticipantAtlas", OleDbType.VarChar).Value = pPascomPhoto.IdParticipantAtlas;
command.CommandTimeout = 15000;
try
{
int data = command.ExecuteNonQuery();
}
catch (Exception e)
{
LogHelper.Log(LogTarget.File, "Fail to insert in database", e);
}
}
}
#endregion
}
Then I use my SQL connection by declaring a new object like so :
_sqlRmSynchro = new Sqlmap();
_sqlPascom = new Sqlmap(true);
As you can see I can call some specific function from the wrong connection string...
What do I need ? A DAL ? What does it look like ?
An error is thrown when there is no data in data base while converting a string value into int.
try {
SqlCommand cmdc = new SqlCommand("SELECT SUM(Credited_amount) FROM IMS_Credit_Dir WHERE Credit_comp_id=1 AND Crdt_typ_id=1", con);
string companya_credit_amount = null, comapnyb_credit_amount = null;
con.Open();
SqlDataReader drc = cmdc.ExecuteReader();
if (drc.HasRows)
{
while (drc.Read())
{
companya_credit_amount = drc[0].ToString();
}
drc.Close();
con.Close();
}
SqlCommand cmdcp = new SqlCommand("SELECT SUM(Credited_amount) FROM IMS_Credit_Dir WHERE Credit_comp_id=2 AND Crdt_typ_id=1", con);
con.Open();
SqlDataReader drcp = cmdcp.ExecuteReader();
if (drcp.HasRows)
{
while (drcp.Read())
{
companyb_credit_amount = drcp[0].ToString();
}
drcp.Close();
con.Close();
}
if (!Page.IsPostBack)
{
int companyA = 0,companyB=0;
if (companya_credit_amount != "") { companyA = Convert.ToInt32(credit_amount.ToString()); }
if (companyb_credit_amount != ""){ companyB = Convert.ToInt32(companyb_credit_amount); }
int total = (companyA+companyB);
count_total_lbl.Text = "Rs." + " " + total.ToString();
count_comapnya_lbl.Text = "Rs." + " " + companya_credit_amount.ToString();
count_companyb_lbl.Text ="Rs."+" "+ companyb_credit_amount.ToString();
}
}
catch(Exception ex) { Label2.Text = ex.ToString(); }
If there is value its working fine.but when there is no value in data base there is an error msg.
System.FormatException: Input string was not in a correct format.
Use IsDBNull to check for null values
Create and destroy all your type instances that implement IDisposable in using blocks. This ensures that connections are always released and resources are cleaned up.
Do not use connections across a class. Create them when needed and then dispose of them. Sql Server will handle connection pooling.
Get the native types directly, not the string equivalent! See changes to GetInt32 instead of ToString on the data reader.
You should refactor this to use SqlParameter's and make the retrieval statement generic OR get both SUM values in 1 sql call.
There is an if (!Page.IsPostBack) statement, if none of this code does anything if it is a postback then check at the top of the page and do not execute the sql statements if it is a postback. Otherwise the code is making (possibly) expensive sql calls for no reason.
try
{
int companyA = 0,companyB=0;
using(var con = new SqlConnection("connectionStringHere"))
{
con.Open();
using(SqlCommand cmdc = new SqlCommand("SELECT SUM(Credited_amount) FROM IMS_Credit_Dir WHERE Credit_comp_id=1 AND Crdt_typ_id=1", con))
using(SqlDataReader drc = cmdc.ExecuteReader())
{
if (drc.Read() && !drc.IsDBNull(0))
companyA = drc.GetInt32(0);
}
using(SqlCommand cmdcp = new SqlCommand("SELECT SUM(Credited_amount) FROM IMS_Credit_Dir WHERE Credit_comp_id=2 AND Crdt_typ_id=1", con))
using(SqlDataReader drcp = cmdcp.ExecuteReader())
{
if (drcp.Read() && !drcp.IsDBNull(0))
companyB = drcp.GetIn32(0);
}
}
// if you are not going to do anything with these values if its not a post back move the check to the top of the method
// and then do not execute anything if it is a postback
// ie: // if (Page.IsPostBack) return;
if (!Page.IsPostBack)
{
int total = (companyA+companyB);
count_total_lbl.Text = "Rs." + " " + total.ToString();
count_comapnya_lbl.Text = "Rs." + " " + companyA.ToString();
count_companyb_lbl.Text ="Rs."+" "+ companyB.ToString();
}
}
catch(Exception ex) { Label2.Text = ex.ToString(); }
Try to replace this
SELECT SUM(Credited_amount)
WITH
SELECT ISNULL(SUM(Credited_amount),0)
Also find one confusing code while converting Credited amount values
if (companya_credit_amount != "") { companyA = Convert.ToInt32(credit_amount.ToString()); }
---------^^^^^
if (companyb_credit_amount != ""){ companyB = Convert.ToInt32(companyb_credit_amount); }
I don't know about your business requirement but What i think Instead of using credit_amount value companya_credit_amount should be use to show value for companyA variable right?
You should do 2 things:
string companya_credit_amount = "", comapnyb_credit_amount = "";
Before assigning the value to these string variable you should check for db null as following:
while (drc.Read())
{
companya_credit_amount = (drc[0] != DbNull.Value) ? drc[0].ToString() : "" ;
}
Similarely
while (drcp.Read())
{
companyb_credit_amount = (drcp[0] != DbNull.Value) ? drcp[0].ToString() : "";
}
Try it.
You need to initialize credit_amount to empty and check if db value is null as shown below:
try {
companya_credit_amount = string.Empty;
companyb_credit_amount = string.Empty;
SqlCommand cmdc = new SqlCommand("SELECT SUM(Credited_amount) FROM IMS_Credit_Dir WHERE Credit_comp_id=1 AND Crdt_typ_id=1", con);
string companya_credit_amount = null, comapnyb_credit_amount = null;
con.Open();
SqlDataReader drc = cmd
c.ExecuteReader();
if (drc.HasRows)
{
while (drc.Read())
{
companya_credit_amount = drcp.IsDBNull(0)?string.Empty:Convert.ToString(drcp[0]);
}
drc.Close();
con.Close();
}
SqlCommand cmdcp = new SqlCommand("SELECT SUM(Credited_amount) FROM IMS_Credit_Dir WHERE Credit_comp_id=2 AND Crdt_typ_id=1", con);
con.Open();
SqlDataReader drcp = cmdcp.ExecuteReader();
if (drcp.HasRows)
{
while (drcp.Read())
{
companyb_credit_amount = drcp.IsDBNull(0)?string.Empty:Convert.ToString(drcp[0]);
}
drcp.Close();
con.Close();
}
if (!Page.IsPostBack)
{
int companyA = 0,companyB=0;
if (companya_credit_amount != "") { companyA = Convert.ToInt32(credit_amount.ToString()); }
if (companyb_credit_amount != ""){ companyB = Convert.ToInt32(companyb_credit_amount); }
int total = (companyA+companyB);
count_total_lbl.Text = "Rs." + " " + total.ToString();
count_comapnya_lbl.Text = "Rs." + " " + companya_credit_amount.ToString();
count_companyb_lbl.Text ="Rs."+" "+ companyb_credit_amount.ToString();
}
}
catch(Exception ex) { Label2.Text = ex.ToString(); }
I have a datagridview which is created by various action and user's manipulation of data. I want to insert all the data of the gridview to the database at once, I know I could try a code similar to this:
private void btnSaveProducts_Click(object sender, EventArgs e)
{
SqlConnection connection = DBConnectivity.getConnection();
if (connection != null)
{
try
{
for (int i = 0; i < dGvProducts.Rows.Count; i++)
{
string query = "INSERT INTO product (productName) " + "VALUES (#productName)";
SqlCommand command = DBConnectivity.getCommandForQuery(query, connection);
int result = command.ExecuteNonQuery();
Console.WriteLine(result + "");
}
// string query = "Insert into units(name,packing)values('" + txtNameUnit.Text + "' , '" + txtPackingUnit.Text + "')";
// SqlCommand command = DBConnectivity.getCommandForQuery(query, connection);
// int result = command.ExecuteNonQuery();
// Console.WriteLine(result + "");
}
catch (Exception ex)
{
}
finally
{
connection.Close();
}
}
}
As is, the code tries to execute a parameterized query but never assigns a value to the parameter. Even if you do, you never extract the cell values.
The code should look like this:
var query = "INSERT INTO product (productName) VALUES (#productName)";
using var(connection = DBConnectivity.getConnection())
using(var command = new SqlCommand(query, connection))
{
var productParam=command.Parameters.Add("#productName",SqlDbType.NVarChar,50);
connection.Open();
for (int i = 0; i < dGvProducts.Rows.Count; i++)
{
var productName=dGvProducts.Rows[i].Cells[somecolumn].Value;
productParam.Value=productName;
int result = command.ExecuteNonQuery();
Console.WriteLine(result);
}
}
I have a DB connection class which executes all of my DB connections
I want to capture the queries and run them on SQL server tuning advisor to find out missing indexes etc
The SQL server profiler tuning takes forever to process. So i want to compose my own file to analyze
The issue is i don't know how should i capture query to properly analyze
Here my SqlCommand function
SQL server 2014 , c# .net 4.5
My question is what parameters, values etc i should log to analyze them perfectly
public static DataTable cmd_SelectQuery(string srCommandText, List<string> lstParameterNames, List<object> lstParameters)
{
DataTable dsCmdPara = new DataTable();
try
{
using (SqlConnection connection = new SqlConnection(DbConnection.srConnectionString))
{
using (SqlCommand cmd = new SqlCommand(srCommandText, connection))
{
cmd.CommandTimeout = PublicSettings.irCommandTimeOutSettings_Second;
cmd.CommandType = CommandType.Text;
object objParameter;
for (int i = 0; i < lstParameterNames.Count; i++)
{
objParameter = lstParameters[i];
if (objParameter == null)
objParameter = "n";
cmd.Parameters.AddWithValue(lstParameterNames[i], lstParameters[i].ToString());
}
using (SqlDataAdapter sqlDa = new SqlDataAdapter(cmd))
{
sqlDa.Fill(dsCmdPara);
return dsCmdPara;
}
}
}
}
catch (Exception E)
{
Interlocked.Increment(ref GlobalStats.long_GlobalSQLErrorCount);
StringBuilder srParameters = new StringBuilder();
if (PublicSettings.blLogSqlParametersOnErrors == true)
{
srParameters.AppendLine("");
srParameters.AppendLine("error at : cmd_UpdateDeleteQuery");
foreach (var vrItem in lstParameters)
{
srParameters.AppendLine("per parameter: " + vrItem + " \r\n\r\n");
}
}
if (PublicSettings.blLogSqlErrors)
ErrorLogger.LogSQL_Error("Error at: cmd_SelectQuery " + srCommandText + " " + E.Message.ToString() + " \r\n" + srParameters.ToString());
}
return dsCmdPara;
}
public static bool cmd_UpdateDeleteQuery(string srCommandText, List<string> lstParameterNames, List<object> lstParameters)
{
try
{
using (SqlConnection connection = new SqlConnection(DbConnection.srConnectionString))
{
using (SqlCommand cmd = new SqlCommand(srCommandText, connection))
{
cmd.CommandTimeout = PublicSettings.irCommandTimeOutSettings_Second;
cmd.CommandType = CommandType.Text;
object objParameter;
for (int i = 0; i < lstParameterNames.Count; i++)
{
objParameter = lstParameters[i];
if (objParameter == null)
objParameter = "n";
cmd.Parameters.AddWithValue(lstParameterNames[i], objParameter);
}
connection.Open();
cmd.ExecuteNonQuery();
return true;
}
}
}
catch (Exception E)
{
Interlocked.Increment(ref GlobalStats.long_GlobalSQLErrorCount);
StringBuilder srParameters = new StringBuilder();
if (PublicSettings.blLogSqlParametersOnErrors == true)
{
srParameters.AppendLine("");
srParameters.AppendLine("error at : cmd_UpdateDeleteQuery");
foreach (var vrItem in lstParameters)
{
srParameters.AppendLine("per parameter: " + vrItem + " \r\n\r\n");
}
}
if (PublicSettings.blLogSqlErrors)
ErrorLogger.LogSQL_Error("Error at: cmd_UpdateDeleteQuery " + srCommandText + " " + E.Message.ToString() + srParameters.ToString());
}
return false;
}
I'm programming a database manager for a gameserver called OTServer, and I'm having problems using executereader() the second time. Here's code:
private void button1_Click(object sender, EventArgs e)
{
Form1 f = new Form1();
MySqlConnection conn = new MySqlConnection();
conn.ConnectionString = "Server=" + f.GetText1().Text + ";Username=" + f.GetText2().Text + ";Pwd=" + f.GetText3().Text + ";Database=" + f.GetText4().Text + ";";
conn.Open();
MySqlCommand cmd = new MySqlCommand("SELECT * FROM `players` WHERE name = #Name", conn);
cmd.Parameters.AddWithValue("#Name", textBox1.Text);
MySqlDataReader Reader = cmd.ExecuteReader(CommandBehavior.SingleRow);
while (Reader.Read())
{
label7.Text = (string)Reader[1];
label7.Show();
label8.Text = Reader[5].ToString();
label8.Show();
if ((int)Reader[6] == 1)
{
label9.Text = "Sorcerer (1)";
}
if ((int)Reader[6] == 2)
{
label9.Text = "Druid (2)";
}
if ((int)Reader[6] == 3)
{
label9.Text = "Paladin (3)";
}
if ((int)Reader[6] == 4)
{
label9.Text = "Knight (4)";
}
if ((int)Reader[6] == 0)
{
label9.Text = "None (0)";
}
label9.Show();
if ((int)Reader[3] == 1)
{
label10.Text = "Player";
}
if ((int)Reader[3] == 2)
{
label10.Text = "Tutor";
}
if ((int)Reader[3] == 3)
{
label10.Text = "Senior Tutor";
}
if ((int)Reader[3] == 4)
{
label10.Text = "Gamemaster";
}
if ((int)Reader[3] == 5)
{
label10.Text = "Community Manager";
}
if ((int)Reader[3] == 6)
{
label10.Text = "God";
}
if ((int)Reader[3] < 1 || (int)Reader[3] > 6)
{
label10.Text = "Unknown";
}
label10.Show();
label13.Text = "Account: " + Reader[4].ToString();
label13.Show();
}
Reader.Close();
cmd = new MySqlCommand("SELECT * FROM accounts WHERE id = #Account_ID", conn);
cmd.Parameters.AddWithValue("#Account_ID", label13.Text);
Reader = cmd.ExecuteReader(CommandBehavior.SingleRow);
while (Reader.Read())
{
label11.Text = (string)Reader[0];
label11.Show();
}
Reader.Close();
}
Suggested solution: Try putting a using block around your DataReader, or call Dispose on it:
using (DataReader Reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
// ...do something with your data reader... then finish by:
Reader.Close();
} // <-- Reader.Dispose() called automatically at the end of using block.
// ...prepare second command...
// the same again for the second command:
using (DataReader Reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
// ...
Reader.Close();
}
Assumed cause of your problem: The DB connection object may do some internal book-keeping to keep track of data readers. I've found out in a similar scenario that you're only allowed one DataReader at a time. So I believe the problem with your code is that, while you Close the Reader, you haven't explicitly Disposed it, so the connection object thinks the first data reader is still in use when you execute the second one.
Besides... why not simplify this code:
if ((int)Reader[6] == 1)
{
label9.Text = "Sorcerer (1)";
}
if ((int)Reader[6] == 2)
{
label9.Text = "Druid (2)";
}
...
to a switch statement?:
int x = (int)(Reader[6]);
string label9Text = string.Empty;
switch (x)
{
case 1: label9Text = "Sorcerer (1)"; break;
case 2: label9Text = "Druid (2)"; break;
...
}
label9.Text = label9Text;
(That would save you quite a bit of repetitive typing.)
Well, assuming that your code is correct you shouldn't have problem in executing two readers as you show in your code. Maybe you have problems because of not disposing commands or something else. I recommend an approach like this (Example made with Northwind db):
using (SqlConnection connection = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=SSPI;"))
{
connection.Open();
using (SqlCommand command = new SqlCommand("SELECT * FROM Orders", connection))
{
using (SqlDataReader reader = command.ExecuteReader(System.Data.CommandBehavior.SingleRow))
{
while (reader.Read())
{
Console.WriteLine(reader.GetString(2));
}
}
}
using (SqlCommand command = new SqlCommand("SELECT * FROM Products", connection))
{
using (SqlDataReader reader = command.ExecuteReader(System.Data.CommandBehavior.SingleRow))
{
while (reader.Read())
{
Console.WriteLine(reader.GetString(1));
}
}
}
}
You should clean your code when recognizing the type of player. Create an enum instead:
public enum PlayerType
{
None = 0,
Sorcerer = 1,
Druid = 2,
Paladin = 3
}
And then do the following while reading:
PlayerType playerType = (PlayerType)reader.GetInt32(6);
label9.Text = playerType.ToString();