I have this program that takes data from a database, puts it into a list, than reads data from a text file, compares two values - one from the text file and one from the database - according to a given index, and returns the higher value to another list. My problem is I can't handle the problem, when a line in the text file is missing an index. When calling function "zwr(index)", it gives a NullReferenceException, but I don't know how to handle it, typing catch nullreferenceexception at the bottom doesn't work and really I don't know where to go from now. I also have to make it so it doesn' crash when the user puts a wrong index. Here is my code, hope somebody can help:
using System;
using FirebirdSql.Data.FirebirdClient;
using System.Collections.Generic;
using System.Linq;
using System.IO;
namespace dokselect
{
class indexstan
{
public string index;
public double standysp;
}
class WynikPorownania
{
public string Indeks;
public int Ilosc;
public override string ToString()
{
return Indeks + " : " + Ilosc;
}
}
class Program
{
public static void Main()
{
try
{
///////CONNECTION
string conn = "database=C:/PCBiznes/BAZA/IXION2_LOGMAG.FB;user=SYSDBA;password=masterkey;DataSource=192.168.24.112;Port=3050";
FbConnection myConnection = new FbConnection(conn);
FbDataReader myReader = null;
string sql = "select KARTOTEKA.indeks,STANMAG.standysp FROM kartoteka INNER JOIN stanmag using(ID_KARTOTEKA) WHERE stanmag.ID_MAGAZYN=10002;";
FbCommand myCommand = new FbCommand(sql, myConnection);
myConnection.Open();
myReader = myCommand.ExecuteReader();
///////LIST lista1
List<indexstan> listadb = new List<indexstan>();
double standysp;
string index;
while (myReader.Read())
{
index = myReader[0].ToString();
standysp = Convert.ToDouble(myReader[1]);
if(standysp<0)
{
standysp = 0;
}
listadb.Add(new indexstan { index=index, standysp=standysp });
//Console.WriteLine(myReader[0].ToString());
}
myConnection.Close();
Console.WriteLine(listadb.Count);
//RETURN STANDYSP FUNCTION
double zwr(string myIndex)
{
var result = listadb.FirstOrDefault(listadb => listadb.index == myIndex).standysp;
return result;
}
//zwr("EMPIS_DESKA_FASOLKA");
//READ FROM TXT AND RETURN HIGHER
string path = "C:/Users/Praktykant/Documents/textdocs/dok1.txt";
List<WynikPorownania> listatf = File.ReadAllLines(path).Select(line =>
{
var linia = line.Split("=");
string index = linia[0];
int value = int.Parse(linia[1]);
if(value<0)
{
value = 0;
}
return new WynikPorownania { Indeks = index, Ilosc = (int)Math.Max(value, zwr(index)) };
}).ToList();
//DISPLAY ALL LISTATF CLASSES
foreach (WynikPorownania WynikPorownania in listatf)
{
Console.WriteLine(WynikPorownania);
}
}
catch (FileNotFoundException ex)
{
Console.WriteLine("Nie znaleziono pliku z podanej sciezki: "+ex);
}
catch (FormatException ex)
{
Console.WriteLine("Podaj indeksy i wartosci w formacie 'indeks=wartosc'. Blad zwrocil: "+ex);
}
catch (NullReferenceException ex)
{
Console.WriteLine("Nie podales prawidlowego indeksu. Blad zwrocil: "+ex);
return;
}
}
}
}
Handling the exception this way:
double zwr(string myIndex)
{
var result = listadb.FirstOrDefault(listadb => listadb.index == myIndex)?.standysp;
return result ?? 0;
}
Gets rid of the error, but still puts the data in the list resulting in something like this:
EMPIS_MAG_BUDOW : 12
: 8 <-Here is where the index wasn't given in the text file
SM_PORTAL_POL1 : 0
And I need it to stop compiling if the index is not given, cause this code will be later a part of a bigger program and this one block of code cannot collapse the whole thing. I tried using diffrent if statements in the function that returns data to the list and tried to throw in exceptions but nothing seemed to work...
Handle it this way:
double zwr(string myIndex)
{
var result = listadb.FirstOrDefault(listadb => listadb.index == myIndex)?.standysp;
return result ?? 0;
}
You are getting the exception, because listadb.FirstOrDefault(listadb => listadb.index == myIndex) is null and you are trying to access .standysp; of null.
So use the ?. which will access the previous statement only when it is not null or return null itself.
The ?? returns the left side if not null and the right side if the left one is null.
Related
I have this program, that I have to handle the exceptions for, but I never done it so I'm kind of confused. I'm guessing I'd have to handle exceptions like the value in the textfile is empty, there is no index, there is no "=" or the file is empty, but I don't really know how to define them or where to put them. Here is my code:
(the lines in the text file should look like this:
EMPIS_MAG_BUDOW=12
EMPIS_DESKA_FASOLKA=2
SM_PORTAL_POL1=-4
)
using System;
using FirebirdSql.Data.FirebirdClient;
using System.Collections.Generic;
using System.Linq;
using System.IO;
namespace dokselect
{
class indexstan
{
public string index;
public double standysp;
}
class WynikPorownania
{
public string Indeks;
public int Ilosc;
public override string ToString()
{
return Indeks + " : " + Ilosc;
}
}
}
class Program
{
public static void Main()
{
///////CONNECTION
string conn = "database=C:/PCBiznes/BAZA/IXION2_LOGMAG.FB;user=SYSDBA;password=masterkey;DataSource=192.168.24.112;Port=3050";
FbConnection myConnection = new FbConnection(conn);
FbDataReader myReader = null;
string sql = "select KARTOTEKA.indeks, STANMAG.standysp FROM kartoteka JOIN stanmag using(ID_KARTOTEKA);";
FbCommand myCommand = new FbCommand(sql, myConnection);
myConnection.Open();
myReader = myCommand.ExecuteReader();
///////LIST lista1
List<indexstan> listadb = new List<indexstan>();
double standysp;
string index;
while (myReader.Read())
{
index = myReader[0].ToString();
standysp = Convert.ToDouble(myReader[1]);
listadb.Add(new indexstan { index=index, standysp=standysp });
//Console.WriteLine(myReader[0].ToString());
}
myConnection.Close();
Console.WriteLine(listadb.Count);
//RETURN STANDYSP FUNCTION
double zwr(string myIndex)
{
var result = listadb.FirstOrDefault(listadb => listadb.index == myIndex).standysp;
return result;
}
//zwr("EMPIS_DESKA_FASOLKA");
//READ FROM TXT AND RETURN HIGHER
string path = "C:/Users/Praktykant/Documents/textdocs/dok1.txt";
List<WynikPorownania> listatf = File.ReadAllLines(path).Select(line =>
{
var linia = line.Split("=");
string index = linia[0];
int value = int.Parse(linia[1]);
return new WynikPorownania {Indeks = index, Ilosc = (int)Math.Max(value, zwr(index))};
}).ToList();
//DISPLAY ALL LISTATF CLASSES
foreach(object WynikPorownania in listatf)
{
Console.WriteLine(WynikPorownania);
}
}
}
}
I tried to make an exception like this, if the value is not given but it doesn't work and the program still collapses when the value in the text file is empty
List<WynikPorownania> listatf = File.ReadAllLines(path).Select(line =>
{
var linia = line.Split("=");
string index = linia[0];
if (linia[1] == "")
{
throw new Exception("Is empty ... or whatever you caught");
return null;
}
else
{
int value = int.Parse(linia[1]);
}
return new WynikPorownania { Indeks = index, Ilosc = (int)Math.Max(value, zwr(index)) };
}).ToList();
To handle exceptions in C# you should use try catch (see c# refence try-catch-finally)
In your code I suggest to wrap a try catch around the firebird connection, since you are depending on this:
try {
// your code
} catch (Exception ex) {
// define what happens if exception is thrown
}
Its key that you include for instance the firebird connection and the while loop into the try, since those are things your code is depending on.
To handle the value in the text file:
//DISPLAY ALL LISTATF CLASSES
// note that I have replaced the "object" with your class.
foreach(WynikPorownania wynikPorownania in listatf)
{
if (wynikPorownania.Indeks != ... || wynikPorownania.Ilosc != ... )
throw new Exception("Is empty ... or whatever you caught");
Console.WriteLine(wynikPorownania);
}
//try something like below.
class Program
{
public static void Main()
{
//CONNECTION
try
{
//... <YOUR CODE>
//DISPLAY ALL LISTATF CLASSES
foreach(object WynikPorownania in listatf)
{
Console.WriteLine(WynikPorownania);
/*if <your condition>
{
throw <your exception1>
}
else if <your condition>
{
throw <your exception1>
}*/
}
}
catch (Exception <your Exception>)
{
// Throw the message
// Or return the code
}
}
}
I am actually programming in C# and I have a problem, I don't know if the method is returning what I want.
In fact i am using a try/catch fonction and I am returning a value (cellValue1) in it and at the end of my method, i am returning" "" ; ".
What does the method return at the end ? I want to return the same value as in the try fonction ?
Here is my code :
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace excel
{
class Class1
{
public static void ReadExcel()
{
Var log = ConstLog.AreaLog.item1;
log+= "\n"
log+= "[REGION]-[read excel] : method read excel started" +"\n";
foreach (var files in Directory.GetFiles(#"C:\Users\Lionel84100\Desktop\Excel"))
{
string filepath = #"C:\Users\Lionel84100\Desktop\Excel\fezfFzfe.xlsx";
try
{
IWorkbook workbook = null;
FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read);
if (filepath.IndexOf(".xlsx") > 0)
{
workbook = new XSSFWorkbook(fs);
}
else if (filepath.IndexOf(".xls") > 0)
{
workbook = new HSSFWorkbook(fs);
}
ISheet sheet = workbook.GetSheet("Formatage_IM");
if (sheet != null)
{
int rowCount = sheet.LastRowNum;
for (int i = 1; i <= rowCount; i++)
{
IRow curRow = sheet.GetRow(i);
string cellValue1 = curRow.GetCell(1).StringCellValue;
return cellValue1;
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw;
}
}
return log;
}
I have replaced string in the starting of the method by a void but there is an error saying that i can't return a value since the method in a void .
the method returns the value of the first cell in the excel file if the file exists, if no, it returns empty string
A method that does not return void must always return a value, except when it returns with an exception.
public string Foo(int i)
{
if (i == 0)
{
return "Zero";
}
// If you remove/comment the following line, the function will not compile.
return "Not Zero";
}
The same applies when there are try/catch handlers in a function:
public string Foo(int i)
{
try
{
if (i == 0)
{
return "Zero";
}
// If you remove/comment the following line, the function will not compile.
return "Not Zero";
}
catch (Exception)
{
// If you remove the following line, the function will also not compile,
// because if you handle an exception in a function, it needs to return a value as well (or rethrow the exception)
return "Error";
}
}
On the other hand (as in your example) a function returning void must not return a value. That means that either there must be no argument after a return statement or no return statement at all.
So for your function, you need to change the return type from void to string and make sure you return a value in the other cases as well (or throw an exception if you don't find the value/cell).
Getting a single value from by SQLite database but I get the error System.InvalidCastException: 'Specified cast is not valid.'
I need only the first value of the select results, tried both First() and ElementAtOrDefault(0) but same thing happens.
Error gets catched when trying to assing to the variable IDPromoMainPage, not before.
Basically this is how I call the value:
private void GetPromoLocal()
{
try
{
var databasePath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "LocalDB.db3");
var db = new SQLiteConnection(databasePath);
IEnumerable<T_Promo> resultado = SELECT_WHERE(db);
if (resultado.Count() > 0)
{
IDPromoMainPage = Convert.ToInt32(resultado.First()); // ElementAtOrDefault(0));
}
}
catch (Exception)
{
throw;
}
}
public static IEnumerable<T_Promo> SELECT_WHERE(SQLiteConnection db)
{
return db.Query<T_Promo>("SELECT IDPromo FROM T_Promo");
}
Also have the same error happening here, exactly at line "PisterosLista = resultado.Cast().ToList();"
List<Pisteros> PisterosLista = new List<Pisteros>();
public void GetPisterosLocal()
{
try
{
var databasePath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "LocalDB.db3");
var db = new SQLiteConnection(databasePath);
IEnumerable<T_Pisteros> resultado = SELECT_WHERE_Pist(db);
if (resultado.Count() > 0)
{
PisterosLista = resultado.Cast<Pisteros>().ToList();
//Console.WriteLine("content :: " + content);
Console.WriteLine("Data :: " + PisterosLista);
}
}
catch (Exception)
{
throw;
}
}
public static IEnumerable<T_Pisteros> SELECT_WHERE_Pist(SQLiteConnection db)
{
return db.Query<T_Pisteros>("SELECT * FROM T_Pisteros");
}
if the column IDPromo is an int, then just do this
IEnumerable<int> resultado = SELECT_WHERE(db);
public static IEnumerable<int> SELECT_WHERE(SQLiteConnection db)
{
return db.Query<int>("SELECT IDPromo FROM T_Promo");
}
I'm getting a thrown exception when attempting to import a SqlDataRecord with a DateTime2 data type. There is no exception thrown in this snippet, but the cause of the later exception is evident in the following code.
using System;
using Microsoft.SqlServer.Server;
using System.Data.SqlClient;
using System.Data;
using System.Web.UI.WebControls;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Diagnostics;
namespace Testing123
{
public class Program
{
public static object SQLTParser(SqlMetaData smd, string val)
{
TypeCode systc = Parameter.ConvertDbTypeToTypeCode(smd.DbType);
try
{
return Convert.ChangeType(val, systc);
}
catch (Exception ex)
{
if (ex is InvalidCastException || ex is FormatException || ex is OverflowException)
{
Console.WriteLine("Exception reached casting " + val + " to " + Type.GetType("System." + Enum.GetName(typeof(TypeCode), systc)) + ": " + ex.Message + ex.ToString()); //smd.GetType().Name
return null;
}
else
{
Console.WriteLine("Null value exception");
return null;
}
}
}
public static void Main()
{
SqlMetaData sqmd = new SqlMetaData("dt", SqlDbType.DateTime2, 27, 7);
SqlDataRecord sdr = new SqlDataRecord(sqmd);
sdr.SetValue(0, SQLTParser(sqmd, "2017-01-12 01:23:12.3456789"));
//set BreakPoint
//sdr -> Non-Public members -> _columnMetaData[0] -> Precision = 27
//sdr -> Non-Public members -> _columnSmiMetaData[0] -> Non-Public members -> Precision = 0
}
}
}
As noted, if you set the breakpoint and watches as indicated in MS Visual Studio*, Precision does not match between columnMetaData and columnSmiMetaData, which by the second such entry (!!) throws an exception:
Metadata for field 'dt' of record '2' did not match the original record's metadata.
which matches the exception thrown by
line 3755 of ValueUtilsSmi
due to the return of MetadataUtilsSmi.IsCompatible
Essentially, precision in the field's metadata of record 2 doesn't match that which is in the SmiMetaData of record 1. In record 1, the MD and SMD don't match either, but based on the logic Microsoft was using for an IEnumerator'd SqlDataRecord, it doesn't become an issue until the 2nd record.
Is this a MS bug? Or is there a way to force the precision value of the SmiMetaData? Or ignore that particular field check in ValueUtilsSmi? Specifying SqlMetaData sqmd = new SqlMetaData("dt", SqlDbType.DateTime2, 0, 7); allows the parsing to proceed, but drops sub-second precision from the data.
Here is, in a nutshell, how I'm attempting to send the data to a database. Apologies if this portion is not a complete example.
public class FullStreamingDataRecord : IEnumerable<SqlDataRecord>
{
private string _filePath;
public bool _hasHeader { get; private set; }
private ParserDict _pd; //notably has colStructure which is an array of SqlMetaData[]
public FullStreamingDataRecord(string FilePath, ParserDict pd)
{
_filePath = FilePath;
_pd = pd;
_hasHeader = true;
}
public static object SQLTParser(SqlMetaData smd, string val)
{
TypeCode systc = Parameter.ConvertDbTypeToTypeCode(smd.DbType);
try
{
return Convert.ChangeType(val, systc);
}
catch (Exception ex)
{
if (ex is InvalidCastException || ex is FormatException || ex is OverflowException)
{
Console.WriteLine("Exception reached casting " + val + " to " + Type.GetType("System."+Enum.GetName(typeof(TypeCode),systc)) + ": " + ex.Message + ex.ToString()); //smd.GetType().Name
return null; //smd.TParse(val);
}
else
{
Console.WriteLine("Null value exception casting...attempting a different method");
return null; smd.TParse(val);
}
}
}
public IEnumerator<SqlDataRecord> GetEnumerator()
{
int len = this._pd.colStructure.Length;
StreamReader fileReader = null;
try
{
using (fileReader = new StreamReader(this._filePath))
{
string inputRow = "";
string[] inputColumns = new string[len];
if (_hasHeader && !fileReader.EndOfStream)
{
inputRow = fileReader.ReadLine(); //and ignore
}
while (!fileReader.EndOfStream)
{
string temp = "";
inputRow = fileReader.ReadLine();
inputColumns = inputRow.Split(new char[]{','},len);
SqlDataRecord dataRecord = this._pd.colStructure
for (int j = 0; j < len; j++) { // i = counter for input columns
string currentKey = this._pd.colStructure[j].SqlMetaData.Name;
string curval = inputColumns[j];
var ty = this._pd.colStructure[j].SqlMetaData; //.DbType;
dataRecord.SetValue(j, SQLTParser(ty, curval));
// dataRecord.GetSqlMetaData(j).Adjust(dataRecord.GetValue(j));
}
yield return dataRecord;
}
}
}
// no catch block allowed due to the "yield" command
finally
{
fileReader.Close();
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
Which I call with this in my Main()
using (SqlConnection conn = new DBConnect().conn)
{
conn.Open();
SqlCommand importProc = new SqlCommand("tvp_"+pd.tableDestination, conn);
importProc.CommandType = CommandType.StoredProcedure;
importProc.CommandTimeout = 300;
SqlParameter importTable = new SqlParameter();
importTable.ParameterName = "#ImportTable";
importTable.TypeName = "dbo.tt_"+pd.tableDestination;
importTable.SqlDbType = SqlDbType.Structured;
importTable.Value = new FullStreamingDataRecord(fn, pd);
importProc.Parameters.Add(importTable);
importProc.ExecuteNonQuery(); //this line throws the exception
}
Apologies for not Console.WriteLineing the values of these watches.
Unfortunately, it seems that these parameters are protected against examination using Reflection's sdr.GetType().GetProperties(), even with the appropriate BindingFlags set. But at least you can see the values in debug mode!
I am using MongoVue application to show the data preview stored in "MongoDb".
In the attached image, the database name "Energy" has collection name "DataLog". In "DataLog", there are several rows. I am adding these row to the collection by reading it from a .CSV file.
Now sometimes the column name Pings has huge data [say array of 2000 items] for a single row due to which the exception occurs i.e if "MaxDocumentSize exceeds in 16MB"
Since the Pings array was huge which threw an exception and to avoid this, I removed the collection of Pings [i.e. entered blank collection] from row and tried to Insert, it went successful.
Now I want to update the Pings for the same entry, but in case the array is something like 2000 elements or above, then I wish to update it in group of 500 items [500 x 4 = 2000] in a loop.
Can anyone help me out.
** SAMPLE CODE **
private void InsertData(Datalog xiDatalog)
{
List<Ping> tempPings = new List<Ping>();
tempPings.AddRange(xiDatalog.Pings);
xiDatalog.Pings.RemoveAll(x => x.RowId != 0);
WriteConcernResult wc = mongoCollection.Insert(xiDatalog);
counter++;
var query = new QueryDocument("_id", xiDatalog.Id);
MongoCursor<Datalog> cursor = mongoCollection.FindAs<Datalog>(query);
foreach (Datalog data in cursor)
{
AddPings(data, tempPings, mongoCollection);
break;
}
}
private void AddPings(Datalog xiDatalog, List<Ping> xiPings, MongoCollection<Datalog> mongoCollection)
{
int groupCnt = 0;
int insertCnt = 0;
foreach (Ping px in xiPings)
{
xiDatalog.Pings.Add(px);
groupCnt++;
if (((int)(groupCnt / 500)) > insertCnt)
{
UpdateDataLog(xiDatalog.Id, xiDatalog.Pings, mongoCollection);
insertCnt++;
}
}
}
private bool UpdateDataLog(BsonValue Id, List<Ping> tempPings, MongoCollection<Datalog> mongoCollection)
{
bool success = false;
try
{
var query = new QueryDocument("_id", Id);
var update = Update<Datalog>.Set(e => e.Pings, tempPings);
mongoCollection.Update(query, update);
success = true;
}
catch (Exception ex)
{
string error = ex.Message;
}
return success;
}
Answer : Just modified the code to use Update.PushAll() instead of Update.Set()
Please refer below code
private bool UpdateDataLog(BsonValue Id, List<Ping> tempPings, MongoCollection<Datalog> mongoCollection)
{
bool success = false;
try
{
var query = new QueryDocument("_id", Id);
var update = Update<Datalog>.PushAll(e => e.Pings, tempPings);
mongoCollection.Update(query, update);
success = true;
}
catch (Exception ex)
{
string error = ex.Message;
}
return success;
}