I am creating an instance of a class from a stored procedure but I get the following error:
Use of unassigned local variable 'member'
I have the following code:
Member member;
while (rdr.Read())
{
member = new member(rdr.GetInt32, rdr.GetString(1)); // Populate Class from Stored Procedure
}
return member
I realise that the compiler does not know that the while loop will always be triggered however what is the cleanest way to solve this without creating a default constructor?
The compiler can't determine whether your condition for loop will be true and member would be initialized. Therefore the error.
Since you are returning member after the loop and instantiation is done inside the loop. It is not guaranteed that member would be initialized/assigned a value. rdr.Read() could return false in first iteration.
You can do:
Member member = default(Member); //null for reference type
while (rdr.Read())
{
member = new member(rdr.GetInt32, rdr.GetString(1)) // Populate Class from Stored Procedure
}
return member;
The other error in your code is usage of rdr.GetInt32, it is a method and should have column ordinal specified like :
rdr.GetInt32(0)
Problem :
You should assign the member variable before while loop, as compiler could not identify wether loop will be executed for sure or not.
you need to specify the column number while using GetInt32() function.
Solution :
assign memebr to null initially.
use required column index in GetInt32() function.
Try This:
Member member=null;
while (rdr.Read())
{
member = new member(rdr.GetInt32(0), rdr.GetString(1)); // Populate Class from Stored Procedure
}
return member;
Related
I use a created query to return a row of values from a key, I have checked on the query executor but when running the program it is returning null. Please help me I'm starting to lose my mind.
I've tried debugging but the problem is coming from the fill data query and it is returning null.
// Add ref. to the Dataset
ViewMedia viewMediaSetInstance = new ViewMedia();
// Create an empty Table
ViewMedia.ViewMediaDataTable viewMediaTable = new ViewMedia.ViewMediaDataTable();
// Create the Adapter we are going to use to populate the Table
Model.ViewMediaTableAdapters.ViewMediaTableAdapter MediaTableAdapter = new Model.ViewMediaTableAdapters.ViewMediaTableAdapter();
//Use query
MediaTableAdapter.findByPublishYear(viewMediaTable, publishYear);
//It doesn't find the row
//I don't seem to find a solution even when the query returns the values in the executer.
//viewMediaTable.Rows.Count == null so doesn't get inside
if (viewMediaTable.Rows.Count > 0)
{
DataRow selectedUser = viewMediaTable.Rows[0];
media = new Media(Int32.Parse(selectedUser["MediaID"].ToString()), selectedUser["Title"].ToString(), Int32.Parse(selectedUser["PublishYear"].ToString()));
return media;
}
else
{
return null;
}
I'm expecting to return the row of data to display in a book display.
This is wonky; you've got strongly typed data rows with proper typed properties for everything, yet you're treating them as generic datarows with string column names, holding objects that you're tostring()ing and parsing. It was never intended to be used this way.
Your code should look more like this:
ViewMedia viewMediaSetInstance = new ViewMedia();
ViewMedia.ViewMediaDataTable viewMediaTable = new ViewMedia.ViewMediaDataTable();
Model.ViewMediaTableAdapters.ViewMediaTableAdapter MediaTableAdapter = new Model.ViewMediaTableAdapters.ViewMediaTableAdapter();
MediaTableAdapter.findByPublishYear(viewMediaTable, publishYear);
//don't need to access the .Rows property to get the count
if (viewMediaTable.Count > 0)
{
//don't need to access the .Rows property to get the data
ViewMediaRow selectedUser = viewMediaTable[0];
media = new Media(selectedUser.MediaID, selectedUser.Title, selectedUser.PublishYear);
return media;
}
else
{
return null;
}
I also disagree with your assertion in the code comments that datatable.Rows.Count is null. A datatable's .Count property is an integer regardless of whether a strongly or weakly typed datatable is in use; it can never be null
You don't need to create a dataset, if you enable creating a method that returns a datatable. Typically these methods are called GetDataByXXX and the fill methods are called FillByXXX (you've called your fill method findByPublishYear). It's configured on the following screen of the TA wizard:
image courtesy of nullskull.com
This can simplify your code to just the following (add a reference to Model.ViewMediaTableAdapters):
var mDT = new ViewMediaTableAdapter().GetDataByPublishYear(publishYear);
Media m = null;
if (mDT.Count > 0)
media = new Media(mDT[0].MediaID, mDT[0].Title, mDT[0].PublishYear);
return m;
Most critically here, DON'T access the first row via the .Rows collection (viewMediaDataTable.Rows[0]) because that returns a base type DataRow. Access it directly via the default property indexer on the strongly typed datatable (viewMediaDataTable[0]) as this will return an object of type ViewMediaRow which in turn has nicely named, typed properties for all the columns in the datatable
viewMediaDataTable[0].PublishYear; //ViewMediaRow is a strongly typed class that has this property as an int
viewMediaDataTable.Rows[0].PublishYear; //"DataRow does not contain a definition for 'PublishYear'"
Now, if any of the data items in the row is null and the setting of the column upon null is "throw exception" you will see an exception of type StrongTypingException- it happens when you have some column that is of a type that cannot be null (such as an int) but it's null because the database query didn't return a value for that row. You were hitting this with your code because som int column (for example) was DBNull.Value and the only thing a datarow will do whn you try to access an int column tha tis DBNull, is throw an exception. By specifying SELECT * in the query, you caused the query to return a value for the column; by not selecting a column the datatable will always treat it as null. You can still also encounter a strongtypingexception if the value of the data in the database is also null. In these cases, use the IsXXXNull() methods to determine if the property is null before trying to access it (causing a strongtypingexception)
Edit: Found the error, I was supposed to get all the columns from the query (using *) and then in the code take what I need otherwise null values get returned.
This question already has answers here:
Modify Struct variable in a Dictionary
(5 answers)
Closed 7 years ago.
I have the following code that will modify a property inside a structure, and the structure is inside a hash table. Each item in hash table has key of (Int) data type and key of (struct Bag), here is the code i have:
struct Bag {
string apple_type;
string orange_type;
};
// Make a new hashtable that will have a key of (int) data type, value of (Bag)
public static Hashtable bags = new Hashtable();
Then i have a method that will read data from a data base reading rows and adding as long there is a row it will add an item (bag(object)) to the hashtable:
public void initHashtbl(){
OleDbConnection db_connector = new OleDbConnection(connection_string);
// Open connection to oracle
db_connector.Open();
OleDbCommand sql_commander = new OleDbCommand(sql_statement, db_connector);
OleDbDataReader data_Reader = sql_commander.ExecuteReader();
// Read data from sql db server and store it in memory ...
Bag tempBag = new Bag();
// row counter used for list view
int row_counter = 0;
while (data_Reader.Read()) { // Keep reading data from memory until there is no row
tempBag.apple_type = data_Reader[0].ToString();
bags.Add(row_counter, tempBag);
row_counter++;
}
for(int bag_item=0;bag_item < bags.Count;bag_item++){
// Get orange type value from another method that uses another sql statement from another table in db ..
((bag) bags[bag_item]).orange_type = getOrangeType(((bag) bags[bag_item]).apple_type);
}
}
How can i access the property of structure that is already inside hash table at later time if i wanted to access it?
Edit:
I'm getting this error:
"Cannot modify the result of an unboxing conversion."
Dictionary will not allow me to modify that directly
Neither will a Hashtable. This has nothing to do with Hashtable vs Dictionary. The problem is that your "value" in either case is a value type, so you can't modify it directly within the collection. If you really need a struct, then you'll have to create a new value and put it back into the hashtable:
bags.Add(1, new Bag() {apple_type="apple1",orange_type="orange1"});
//((Bag)bags[1]).apple_type="apple2";
var bag = (Bag)bags[1];
bag.apple_type = "appple2";
bags[1] = bag;
But mutable structs are generally bad, so I would either get the value of the struct right the first time (rather than modifying it ourside of the initial load loop) :
// row counter used for list view
int row_counter = 0;
while (data_Reader.Read()) { // Keep reading data from memory until there is no row
{
var appleType = data_Reader[0].ToString();
Bag tempBag = new Bag() {
apple_type = appleType,
orange_type = getOrangeType(appleType)
};
bags.Add(row_counter, tempBag);
row_counter++;
}
or use a class.
Note that the same code works exactly the same way whether you use a Hashtable or a Dictionary.
Also, since your "key" is just an incrementing number (and not tied to the value at all), you could just as well use a List<Bag> and access the items by index.
This code worked for me to read an item:
string orangeType = ((Bag) bags[0]).orange_type;
To modify an item, I think you must create a new Bag and replace the existing one like this:
bags[0] = newBag;
If you try to modify the properties of a bag in the HashTable, then you get the error you reported above.
Because of how value types work, the boxed Bag is a copy of the original, and "unboxing" it by casting back to Bag creates yet another copy. From the C# language spec:
When a value of a value type is converted to type object, an object
instance, also called a “box,” is allocated to hold the value, and the
value is copied into that box. Conversely, when an object reference is
cast to a value type, a check is made that the referenced object is a
box of the correct value type, and, if the check succeeds, the value
in the box is copied out.
Modifying the copy wouldn't change the original anyway, so it wouldn't make much sense to allow it.
Corrections:
To fix your error and to allow modifications to your HashTable of Bag's you should change your value type to reference type:
public class Bag
{
public string apple_type { get; set; }
public string orange_type { get; set; }
};
Here is my code:
private Analyst _PrimaryAnalyst;
public Analyst PrimaryAnalyst
{
get
{
Analyst activeAnalysts;
if (this.PrimaryAnalyst.IsActive == true)
{
activeAnalysts = _PrimaryAnalyst;
}
return activeAnalysts; //"Use of unassigned local variable"
}
set
{
SetPropertyValue("PrimaryAnalyst", ref _PrimaryAnalyst, value);
}
}
Basically I am trying to filter my Analyst property based on if they are marked Active or not. Then I want to to return only Active Analysts. (Based on a bool property of Analyst), I am getting an error on the return statement saying "Use of unassigned local variable"
However I am clearly assigning it in the if statement?
In C# you can not use a local variable before assigning it a value.
C# Language Specification, section 1.6.6.2
C# requires a local variable to be definitely assigned before its
value can be obtained
lets get to your code
what happen if this.PrimaryAnalyst.IsActive is false? Yes, Use of unassigned local variable
you can fix this by initializing the local variable.
Analyst activeAnalysts = null;
or
if (this.PrimaryAnalyst.IsActive == true)
{
activeAnalysts = _PrimaryAnalyst;
}
else
{
activeAnalysts = null;
}
but there is another problem here. Your code leads to StackOverflowException because you are calling a method inside itself (recursion) but there is no way out of it so it leads to StackOverflowException
you should change the line this.PrimaryAnalyst.IsActive == true to _PrimaryAnalyst.IsActive == true
Change the first line of the getter to:
Analyst activeAnalysts = null;
The issue is that if the if statement evaluates to false, then the value is never set, so the compiler doesn't know what it should return.
The reason you're getting the error is that not all code paths lead to an assignment. You should either initialize the variable before the if, or include an else and assign it to something there.
Also, you should be checking your private variable in the if statement instead of the public one (to avoid a StackOverflowException), and, assuming that Analyst is a nullable class, you should also ensure it's not null before checking IsActive. A property getter should not throw an exception.
Your getter can be also be simplified using a ternary assignment:
get
{
return (_PrimaryAnalyst != null && _PrimaryAnalyst.IsActive)
? _PrimaryAnalyst
: null;
}
I am getting a
'System.Collections.Generic.KeyNotFoundException' occurred in mscorlib.dll
when i run my code, everthing seems to be fine, i have been unable to find the bug. Here is path of my class caling my get/set
foreach (Tran transaction in transactions)
{
Account sAcc = items[transaction.ID1];//getting error here
Account dAcc = items[transaction.ID2];
decimal tempResult = sAcc.Money - transaction.Amount;
foreach (char s in sAcc.BorP)
Console.WriteLine(s);
And here is my get/set class
public class Tran
{
public int ID1 { get; set; }
public int ID2 { get; set; }
public decimal Amount { get; set; }
}
It was running before and i ran some more test and i keep getting this error and dont know what could be causing int. Thanks for you help
You can use the TryGetValue method of the dictionary.
Here is a sample code of using
object result; // Un-Initialized instance result
myCollection.TryGetValue("Test", out result); // If the key exists the method will out the value
Grabbed from another SO post.
From MSDN's entry on Dictionary.TryGetValue Method:
This method combines the functionality of the ContainsKey method and
the Item property.
If the key is not found, then the value parameter gets the appropriate
default value for the value type TValue; for example, 0 (zero) for
integer types, false for Boolean types, and null for reference types.
Use the TryGetValue method if your code frequently attempts to access
keys that are not in the dictionary. Using this method is more
efficient than catching the KeyNotFoundException thrown by the Item
property.
This method approaches an O(1) operation.
Also reference in this post to lookup the performance of Indexer vs TryGetValue
What is more efficient: Dictionary TryGetValue or ContainsKey+Item?
The issue you are having is that the items you are trying to read from the items array don't exist.
Use either
if (items.ContainsKey(transaction.ID1) && items.ContainsKey(transaction.ID2))
{
// Your code.
} else {
// Signal an error.
}
Or if you have a default account class that you want to use when the transactions do not exist you could use something like this.
if (!items.TryGetValue(transaction.ID1, out sAcc))
items.Add(transaction.ID1, sAcc = new Account);
if (!items.TryGetValue(transaction.ID2, out dAcc))
items.Add(transaction.ID2, dAcc = new Account);
// Your code.
Otherwise if the transaction ID:s should always be in item the problem with your code is likely outside of the code snippets you shared here. I would check what the ID:s are you are trying to look up and do a sanity check.
In my Index Action in my Controller I have this:
public ActionResult Index(string sortOrder)
{
var model;
ViewBag.CitySortParm = String.IsNullOrEmpty(sortOrder) ? "City_desc" : "";
switch (sortOrder)
{
case "City_desc":
model = this.UnitOfWork.AddressRepository.Get().OrderBy(a => a.City);
break;
}
return View(model);
}
This doesn't work, I always get the error: Implicitly-typed local variables must be initialized
Why doesn't this work and how can I fix this?
Why doesn't this work
Two reasons:
You're trying to use var without specifying an initial value. You can't do that - the compiler can't infer the type.
You're trying to read from the model variable when it may not be initialized - if sortOrder isn't City_desc what would you expect to be returned? And what would that type be?
and how can I fix this?
That depends on what you want to happen if sortOrder isn't City_desc. Work out what value you'd want to return, and make sure it's returned.
Basically, you can't read from a local variable until it's definitely assigned - in other words, until the compiler can prove (by the rules of C#) that by the time you get there, it will have been assigned a value.
In terms of the implicit typing - are you always going to use the same type for your view? If so, just explicitly declare the type of model, as well as fixing the definite assignment part. If not, I'd consider returning within the switch/case statement - I don't think your model local variable is actually helping you much.
The first problem is that the type of the model variable cannot be inferred if you just declare it with var model;.
You should explicitly declare its type.
Also, as Jon Skeet correctly pointed out, you must initialize your model somehow before the return... call. Try to imagine what you model's value is if sortOrder is not "City_desc"...
Implicitly-typed local variables must be initialized
Yes will have to initialize it inline to make it work.
var model = default(MyType);//This should work
Or just declare the type explicitly.
MyType model = default(MyType);//Or null if it is a reference type
You have to initialize an implicitly declared variable before using it. A simple example:
var x;
if(true)
x = "true";
This will get you the same error. This should be hapening:
var x = "";
if(true)
x = "true";
Same goes for your code. Initialize it before using it. Say your model is of type AddressViewModel, then this should work:
var model = new AddressViewModel();
ViewBag.CitySortParm = String.IsNullOrEmpty(sortOrder) ? "City_desc" : "";
switch (sortOrder)
{
case "City_desc":
model = this.UnitOfWork.AddressRepository.Get().OrderBy(a => a.City);
break;
}
return View(model);