NullReference Exception was unhandles - c#

I'm having trouble when adding new team to the dataTable. VisualStudio is pointing at line teams.Rows.Add(dr) with NullReference error. Can you please help me?
private void addTeam(String nazwa)
{
DataRow dr = players.NewRow();
//dr["playerID"] = nazwa;
dr["nazwa"] = nazwa;
teams.Rows.Add(dr); //<--there is en error
}
class Program
{
static DataTable players ;
static DataTable teams;
private DataSet teamMenager;
static void Main(string[] args)
{

The DataTable is not yet initialized
static DataTable teams;
You can initilaize it for example with the default constructor:
static DataTable teams = new DataTable();
static DataTable players = new DataTable();
Although it's not clear why you made them static. This would mean that every instance of Program would share the same DataTable which can be problematic with multiple threads since you need to provide a locking mechanism. Just remove the static and create an instance of Program:
static void Main(string[] args)
{
Program p = new Program();
p.Start(); // open your form(s) there and add teams or what else
// ...
Edit: There's something else wrong. You're creating the new DataRow via players.NewRow but adding it to the DataTable teams. That is not allowed. Every DataRow belongs to one DataTable. That cannot be changed and will result in an ArgumentException.
DataRow dr = players.NewRow();
dr["nazwa"] = nazwa;
so add it to players instead:
players.Rows.Add(dr); //<--there is en error

Related

Odd effect of async / await on loading a datatable

I'm struggling to understand what is going on with this code. I've done async/await for a while now but haven't stumbled on this issue before (unless I'm just not seeing what I've done)
I'm loading a CSV file into a DataTable then I want to pull the list of column names from the DataTable to manipulate later.
In the first method, I load the CSV async then assign the DataGrid to view the data. I wasn't able to use the _ColumnList = ... in the first method because for whatever reason, the "_dtSampleCSV.Columns" did not resolve; it's not seeing that it's a DataTable.
So I moved that line to another method where it pulls the column names and assigns those names to another DataGrid. When it hits this method, there's no data in the _dtSampleCSV DataTable (no rows, no columns), yet the first DataGrid does populate with data.
I've always assumed that using an "await" waits for the thread to complete before proceeding. So either that's not true, or the thread did complete but the DataTable wasn't assigned yet.
I can only assume the data doesn't exist at that point, but the DataGrid's source is set so when the data is populated; it shows. But how do I prevent execution if await isn't completing the dataload into the DataTable?
private DataTable _dtSampleCSV = new DataTable();
private List<string> _ColumnList = new List<string>();
private async void btnAdd_Click(object sender, RoutedEventArgs e)
{
spNew.Visibility = Visibility.Visible;
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == true)
{
tbFilePath.Text = openFileDialog.FileName;
var _dtSampleCSV = await LoadCSVAsync(openFileDialog.FileName);
dgCSVExample.DataContext = _dtSampleCSV;
dgCSVExample.Visibility = Visibility.Visible;
SetColumnGrid();
}
}
private void SetColumnGrid()
{
_ColumnList = (from DataColumn dc in _dtSampleCSV.Columns.Cast<DataColumn>() select dc.ColumnName).ToList();
dgColumnNames.DataContext = _ColumnList; // breakpoint set here to look at _dtSampleCSV and no data exists at runtime
dgColumnNames.Visibility = Visibility.Visible;
}
// csv method
public static async Task<DataTable> LoadCSVAsync(string filePath)
{
using (var reader = File.OpenText(filePath))
{
var fileText = await reader.ReadToEndAsync();
using (TextReader sr = new StringReader(fileText))
{
var adapter = new GenericParsing.GenericParserAdapter(sr);
adapter.FirstRowHasHeader = true;
adapter.MaxBufferSize = 4096;
adapter.MaxRows = 3;
DataTable dtProcess = adapter.GetDataTable();
return dtProcess;
}
}
}
Your LoadCSVAsync method is static, which explains why it can't access the _dtSampleCSV instance field.
Your btnAdd_Click method creates a local variable called _dtSampleCSV, assigns that to the dgCSVExample.DataContext, and then throws it away. Data from that local variable will not be available in the _dtSampleCSV field.
Change your method so that it assigns the data to the field, rather than creating a local variable:
// Remove this:
// var _dtSampleCSV = await LoadCSVAsync(openFileDialog.FileName);
// Use this:
_dtSampleCSV = await LoadCSVAsync(openFileDialog.FileName);
NB: You should try to avoid async void methods wherever possible.

How to add a progressbar and status to a process that doesnt have a count like copying files does?

So i had posted a question on getting my sample project working and it now works.. Sample Project
And thats great because as in that example i have a production project that requires copying files, so that will work great for that one.
But this question is about displaying a progress bar to a process that im not clear on how to implement.
Im reading a excel file using closedxml, i read that file into a datatable in order to perform some filtering and other things in order to populate some listboxes on my form, how can my sample code in my other post be implemented against the creation of 5 or 6 data tables?
I can provide some of the datatable creation methods, but the over all code is close to 600 lines right now and not finished yet.. so below is a stripped down sample of the current code im working with..
private void sample()
{
string plink = #"C:\Test\Sizes.xlsx";
string[] DistinctDept = { "Dept Code", "Dept Description" };
DataTable ListDept = GetDistinctRecords(LoadExceltoDatatable(plink), DistinctDept);
ListDept.Columns.Add(new DataColumn("DeptCombo", typeof(string), "'('+[Dept Code] +') ' + [Dept Description]"));
if (string.IsNullOrEmpty(ListDept.Rows[0]["Dept Code"].ToString()))
{
ListDept.Rows[0].Delete();
ListDept.AcceptChanges();
}
lbDept.DataSource = ListDept;
lbDept.DisplayMember = "DeptCombo";
lbDept.ClearSelected();
}
public static DataTable GetDistinctRecords(DataTable dt, string[] Columns)
{
DataTable dtUniqRecords = new DataTable();
dtUniqRecords = dt.DefaultView.ToTable(true, Columns);
return dtUniqRecords;
}
public static DataTable LoadExceltoDatatable(string sizeoptcalc)
{
using (var wb = new XLWorkbook(sizeoptcalc, XLEventTracking.Disabled))
{
var ws = wb.Worksheet(1);
var foundMonth = ws.Search("Month", System.Globalization.CompareOptions.OrdinalIgnoreCase);
var monthRow = foundMonth.Last().Address; // A11
var lastcell = ws.LastCellUsed().Address; // BC3950
DataTable dataTable = ws.Range(monthRow, lastcell).RangeUsed().AsTable().AsNativeDataTable();
return dataTable;
}
}
Can this be changed to report the progress? I mean in some cases the excel files are large and do take some time to fill in my listboxes.
Here are more of the datatable creations that i would like to account for the overall progress of them

'System.StackOverflowException' occurred in mscorlib.dll and use two connection strings

I am using inside my project 2 different datasets for 2 different connection strings, but when I create and start one of my classes, I get the StackOverflowException.
The code where I get the exception is:
public class myObject : EventClass
{
public myDataPathStruct dataPath = new myDataPathStruct();
public myData data = new myData();
public periodDownload myPeriod = periodDownload.All;
private MainDataSet.tbMyDataDataTable myTable = new MainDataSet.tbMyDataDataTable();
private tbMyDataTableAdapter myAdapter = new tbMyDataTableAdapter();
private Downloader download = new Downloader();
private DBFiller dbfiller = new DBFiller();
}
I get the exception at the moment that I inicialize the Dataset variables. I use the Connection Strings at the settings and each connection string is declared also in each one of my datasets.
Do I miss something or should I approach this solution of another way?

public dataset in C#

i need to be able to save and retrieve data in a dataset in multiple places. i didnt want to copy and paste all my code since its pretty large, and i hope my super short version gets the idea across. thanks in advance. i currently have something along the lines of...
class program
{
DataSet ds;
static void main(...)
{
getMe(string);
}
public void getMe(string x)
{
ds = new mydataset();
DataRow dr = new ds.Tables[0].NewRow();
//blah blah add x to dr[ column ]
ds.Tables[0].Rows.Add(dr.ItemArray);
}
public void readMe()
{
**need to read dataset here with info added in rows from getMe()
}
}
EDIT:
edited DataSet = ds; to DataSet ds; to reflect my actual code.
if i call getMe(string) in my main, it errors with..."an object reference is required for a non-static field, method or property."
if i change getMe(string x) to public static void getMe(string) the error goes away but shows again for
ds = new mydataset();

Visual C# Dataset to Class

I am a student programer working in Visual Studios C# and I am trying to access information from my dataset and insert the data into a class. This is not, by any means, homework I've just have some personal projects I've been wanting to try. I have tried several approaches that have been mentioned on this site; however, no information is displayed. My code looks similar to this:
class MyClass
{
public string ColumnData1
{
get; set;
}
public int ColumnData2
{
get; set;
}
public string Display()
{
string MyString = ColumnData1 + ColumnData2.ToString();
return MyString;
}
}
I use this to insert data into class:
private void MyForm_Load(object sender, EventArgs e)
{
MyDataSet.MyDataTable MDT = new MyDataSet.MyDataTable();
List<MyClass> MyList = new List<MyClass>();
foreach (DataRow MyDataRow in MDT.Rows)
{
Mylist.Add(new MyClass()
{
ColumnData1 = (string)MyDataRow["Data1"],
ColumnData2 = (int)MyDataRow["Data2"]
{
}
Lastly to display the information:
textBox1.Text = Mylist[0].Display();
}
In the end, however, nothing ends up displaying. This also wasn't the only thing I've tried to display the information.. it's like the information doesn't exist. I don't receive any errors and when I try to add a "Stop Point" at the insertion part of the code it just skips it. I should mention also that I have many text boxes and list boxes that pull data off the database just fine, of course Visual Studios binds those for me. Any help is very much appreciated.
Edit:
Ok, excluding the new data table. If I had an existing dataset how would I would I use it to fill my class.
That's normal because your DataTable is empty (Your create instance)
MyDataSet.MyDataTable MDT = new MyDataSet.MyDataTable();//<------Empty
foreach (DataRow MyDataRow in MDT.Rows)
{
....
}
Fill DataSet :
string queryString =
"SELECT .... FROM YourTable";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);
DataSet dataSet = new DataSet();
adapter.Fill(dataSet, "NameOfDataSet");
You must have some data in MDT before you insert it in the MyList, List of MyClass.
Declaration without data:
MyDataSet.MyDataTable MDT = new MyDataSet.MyDataTable();

Categories

Resources