I would like your help on how to handle and exception in C# if ExecuteScalar is null. Am trying it but am getting a null reference exceprion. This is my code
public async Task<int> SumItemAsync()
{
Object data = await db.ExecuteScalarAsync<int>("SELECT
SUM(Amount) FROM Spent");
if (data != null)
{
return Convert.ToInt32(data);
}
else
{
return 0;
}
}
I believe that the problem is that your query returns null but you tell ExecuteScalarAsync that is should be an int. Change it to a nullable int.
var data = db.ExecuteScalarAsync<int?>("SELECT SUM(Amount) FROM Spent")
return data ?? 0;
You can then simplify the return expression a little bit.
I actually didn't solve it by using your code but you mentioned that my query returns null but I tell ExecuteScalarAsync that is should be an int. So from your statement I did it like this and it worked. Thanks anyway
public async Task SumItemAsync()
{
var data = await db.ExecuteScalarAsync<String>("SELECT SUM(TotalAmount) FROM Spent");
if (data != null)
{
return data;
}
else
{
return "0.00";
}
Related
It's a WINDOWSFORM
I have combobox, I use this code for auto textboxvalue but I receive this error
Sequence contains no elements
private void cmbOfficeNumber_SelectedIndexChanged(object sender, EventArgs e)
{
using (UnitOfWork db = new UnitOfWork())
if (cmbOfficeNumber.SelectedValue.ToString() != null)
{
txtOfficeName.Text = db.OfficeRepository.GetOfficeNamebyNumber(cmbOfficeNumber.Text);
}
}
And this is my repository code
public string GetOfficeNamebyNumber(string officeNumber)
{
return db.Office.First(g => g.OfficeNumber == officeNumber).OfficeName;
}
EDIT: When using
return db.Office.FirstOrDefault(g => g.OfficeNumber == officeNumber).OfficeName;
I receive a different error
Object reference not set to an instance of an object
If First() results in
Sequence contains no elements
That means the condition in the lambda expression resulted in no hits. Because First requires you to have atleast one match.
If FirstOrDefault().Property results in
Object reference not set to an instance of an object
It means that the lambda expression resulted in no hits, and it returns a default value of the return type. In the case of a reference object it will be null. You then tried to access a property of null which causes the exception.
Simply put. Your problem is that your comparison is returning no hits.
You need to insert a fail safe for this to not crash
Something like:
public string GetOfficeNamebyNumber(string officeNumber)
{
var result = db.Office.FirstOrDefault(g => g.OfficeNumber == officeNumber);
if(result == null)
return string.Empty;
return result.OfficeName;
}
This can also be shortend to
public string GetOfficeNamebyNumber(string officeNumber)
{
var result = db.Office.FirstOrDefault(g => g.OfficeNumber == officeNumber);
return result?.OfficeName ?? string.Empty;
}
Or even
public string GetOfficeNamebyNumber(string officeNumber)
{
return db.Office.FirstOrDefault(g => g.OfficeNumber == officeNumber)?.OfficeName ?? string.Empty;
}
I hope this step by step explanation gives you the information you need to solve the problem.
I have code that is possibly fragile. This statement here
int countDis = (int)cmd.ExecuteScalar();
If I change the stored procedure to not return ANYTHING, then that casting to (int) is going to blow up. If I simply remove it, then I cannot compile.
What is the best code practice for defensive coding in this situation?
Just change the code as:
int countDis = Convert.ToInt32(cmd.ExecuteScalar());
This will ensure that even if ExecuteScalar returns null, as result of not selecting anything in stored procedure, countDis will have a value of 0. Because Convert.ToInt32(null) = 0.
Update (10/12/2018)
Safer version. Thanks #Moe for highlighting DBNull case.
object result = cmd.ExecuteScalar();
result = (result == DBNull.Value) ? null : result;
int countDis = Convert.ToInt32(result);
I usually use nullable types. e.g. :
string str;
int? countDis = cmd.ExecuteScalar() as int?;
if (countDis == null)
str = "count is null";
else
str = "Count is : " + countDis.Value;
This will work for whether ExecuteScalar returns null or DBNull.Value.
You can check the scalar value before cast.
var result = cmd.ExecuteScalar();
int countDis =result != null ? int.Parse(result) : 0;
Because ExecuteScalar can return DBNull, the best way there I found is:
var result = cmd.ExecuteScalar();
int countDis = result != null ? Convert.ToInt32(result) : 0;
if you treat a result of DBNull.Value as the same as null in that they should both be 0, you can use a single line, though you're still using a temporary variable. I won't speak of execution speed:
int countDis = int.TryParse(cmd.ExecuteScalar()?.ToString(), out int temp) ? temp : 0
You can use to get as Object, and check its type then take your decision:
object obj = cmd.ExecuteScalar();
if (obj.GetType() == typeof(string))
{
//you can do your stuff with STRING
}
else if (obj.GetType() == typeof(int))
{
//you can do your stuff with INT
}
else
{
//add here ANYOTHER type you many want in future...
}
I am trying to store the result of a select query. The value being returned is stored as an integer in Sqlite.
I decided to try what was presented in this answer: https://stackoverflow.com/a/870771
My code is currently:
cmd.CommandText = "SELECT id FROM TVShows WHERE id = #id";
cmd.Parameters.Add(new SQLiteParameter("#id", id));
conn.Open();
object result = ConvertFromDBVal<int>(cmd.ExecuteScalar());
private T ConvertFromDBVal<T>(object obj)
{
if (obj == null || obj == DBNull.Value)
{
return default(T); // returns the default value for the type
}
else
{
return (T)obj;
}
}
However, I am receiving the error:
System.InvalidCastException at this line:
return (T)obj;
If I simply try and store the result of cmd.ExecuteScalar()) as an int, I get the same error.
I must admit I don't completely understand this function and so if someone could shed some light on that as well, I'd greatly appreciate it!
Per the comments, you cannot cast a long to an int. By passing in long, you will not have a cast exception.
long result = ConvertFromDBVal<long>(cmd.ExecuteScalar());
I am having this Linq To SQL query which is taking Customer Category from database.The CustCategory will be defined already.Here is the query.
public IList<string> GetAccountType()
{
using (var db = new DataClasses1DataContext())
{
var acctype = db.mem_types.Select(account=>account.CustCategory).Distinct().ToList();
if (acctype != null)
{
return acctype;
}
}
}
Currently I am getting an error that Not all code paths return a value.If I am always certain that the value is there in the database then do I need to check for null,If I need to check for null then how do I handle this.
Can anyone help me with this.
Any suggestions are welcome.
Since Enumerable.ToList never returns null (see the Return Value section of the documentation), you can safely remove the if.
EDIT: Note that, no matter what your database contains, acctype will never be null:
If no value is found in the database, the return value will be an empty list (which is different than null).
If one record is found and its value is null, the return value will be a valid list with one entry, whose value is null. Still, the list itself is not null.
What happens if:
if (acctype != null)
Is null? What is your method supposed to return?
You need to return something
This is not about LINQ to SQL, the method GetAccountType() must return IList<string>. You should return return acctype; and then check this returned list later using Any(), something like:
if(GetAccountType.Any()){
//not empty
}
How about something like this for a fairly clean and readable solution?:
(Note, updated: removed the check for null, since it would clearly not have any effect).
public IList<string> GetAccountType()
{
var acctype = new List<string>();
using (var db = new DataClasses1DataContext())
{
acctype = db.mem_types.Select(
account=>account.CustCategory).Distinct().ToList();
}
return acctype;
}
You need to return a value from your function:
public IList<string> GetAccountType()
{
using (var db = new DataClasses1DataContext())
{
var acctype = db.mem_types.Select(account=>account.CustCategory).Distinct().ToList();
if (acctype != null)
{
return acctype;
}
}
return acctype;
}
I just want to know what is the best way to check if an IQueryable result has no values.
eg. if we have a method like
public static IQueryable<Table> DisplayAll()
{
var db = new DataContext();
var list= from data in db.Table select data;
return list;
}
and then we do something like this
var list = DisplayAll();
if(list != null)
{
//do something --- in here even if the result set has no values it will
// go to this line. It just say `enumeration yielded no results`
}
Any possible way to check the result set has content or not??
Thanks
list will never be null with LINQ; it will simply represent an "empty collection" if need be. The way to test is with the Any extension method:
if (list.Any()) {
// list has at least one item
}
An exception will be thrown if IQueryable yeilds no result. I use:
using System.Data.Entity; //for Async support in EF
var tQ = await _tableRepository.DisplayAll();
try { return await tQ.ToListAsync(); }
catch { return null; }
to trap the exception and return null; or an empty List if you prefer,
catch { return new List<Table>(); }
Here is what works for me:
public IQueryable SomeFunc()
{
IQueryable result = Repo.SomeLinqQuery();
if (result.GetEnumerator().MoveNext() == false)
{
throw new Exception("Results empty");
}
return result;
}