I'm trying to get values from my database, it works when all columns have values. When a value is NULL, it returns an error.
I've managed to find a way to handle with the strings but if there's an integer I don't know how to handle it. I've tried to find a solution but none has worked for me so far! Here's the code, any help would be highly appreciated.
Thanks!
while (dr.Read())
{
coments comentsar = new coments
{
Id = (int)dr["Id"],
Name = (string)dr["Name"],
Likes = (int)dr["Likes"],
// Signature = dr["Signature"].ToString(),
Datetime = (DateTime)dr["Datetime"]
};
comen.Add(comentsar);
return comen;
}
You can check for null value and if the value is not null assign the variable using ternary operator:
Signature = dr["Signature"] != DBNull.Value ? (string)dr["Signature"] : "No value",
Likes = dr["Likes"] != DBNull.Value ? Convert.ToInt32(dr["Likes"]) : 0,
You need to change your types to Nullable types.
Change (int)dr["Likes"] to (int?)dr["Likes"]
and Datetime = (DateTime)dr["Datetime"] to Datetime = (DateTime?)dr["Datetime"].
You will also need to update your model coments to allow for nullable types.
Microsoft Nullable Types.
Related
What I'm going for? I need to post a newly created object to a db, the incoming object may have a null value. The created object is set to #nullible true where needed.
When data comes in and I land on a null string in my object I get a null reference and land on catch.
My code:
Objects.Data.Info.StoredData postData = new Objects.Data.Info.StoredData
{
Name = data.data.Name,
Type = data.data.Type,
Price = data.data.Price,
Indicator = data.data.Indicator,
Scan = data.data.Scan,
Comment = data.data.Extra
};
db.Information.Add(postData);
db.SaveChanges();
data.data.Extra can be null, sometimes.
I would usually write if statements to counter this, but don't feel like it's the best practice here. What direction should I go? I've checked a few other questions and msdn and can't find a clear path.
Thanks.
You can succinctly default to an empty string when the property is null by using the ?? operator, like so:
Comment = data.data.Extra ?? ""
//the value on the right is used if the expression on the left is null
?? is called the 'null-coalescing' operator: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-coalescing-operator
If you also want to handle the intermediate properties being null (which I don't think applies to this case but is good to know), and still want to default to an empty string, you can combine this with Eugene's suggestion of using ?. like so:
Comment = data?.data?.Extra ?? ""
?. is called the 'null-conditional' operator: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and-
var postData = new Objects.Data.Info.StoredData
{
Name = data.data.Name,
Type = data.data.Type,
Price = data.data?.Price,
Indicator = data.data.Indicator,
Scan = data.data.Scan,
Comment = data.data.Extra
};
db.Entry(postData).State=EntityState.Added;
db.SaveChanges();
I thought that you have facing difficulty with Price attribute because this one is Not null in your db once your programming cursor over there it failed, so once you exactly do what I did then eventually you change this nullable and then easily check or insert on runtime.
You should use the Null Conditional Operator (?.), like this:
data?.data?.Name
This will prevent an NullReferenceException if data or data.data is null.
So I have this property and would like to either set the value to what is coming back from the db or to null if it is empty. It is possible to do this with an if-else, but for cleaner code, I would like to use the ternary operator. Could someone point out the mistake I am making. Thanks!!!
public DateTime? OptionExpiration {get;set;}
//actually sets the value to null
if(String.IsNullOrEmpty(dr["OPTION_EXPIRATION"].ToString())){
OptionExpiration = null;
}else{
OptionExpiration = DateTime.Parse(dr["OPTION_EXPIRATION"].ToString());
}
//so I check the to see if the string is empty or null, then try to set the value but recieve this error: Error 2 Operator '|' cannot be applied to operands of type '' and 'System.DateTime?'
String.IsNullOrEmpty(dr["OPTION_EXPIRATION"].ToString())
? OptionExpiration = null
| OptionExpiration = DateTime.Parse(dr["OPTION_EXPIRATION"].ToString())
;
You are using the ternary operator wrong.
It should be:
OptionExpiration = String.IsNullOrEmpty(Convert.ToString(dr["OPTION_EXPIRATION"]))
? (DateTime?)null
: DateTime.Parse(dr["OPTION_EXPIRATION"].ToString())
;
So:
assignment = condition ? trueExpression : falseExpression;
If the field is a date in your database, it might be better to do this:
OptionExpiration = Convert.IsDBNull(dr["OPTION_EXPIRATION"])
? (DateTime?)null
: (DateTime)dr["OPTION_EXPIRATION"]
;
I would use an extension method like this:
public static Nullable<DateTime> AsNullableDateTime(this object item, Nullable<DateTime> defaultDateTime = null)
{
if (item == null || string.IsNullOrEmpty(item.ToString()))
return defaultDateTime;
DateTime result;
if (!DateTime.TryParse(item.ToString(), out result))
return defaultDateTime;
return result;
}
You can pass anything in to this and it will attempt to give you back a date. If it fails for whatever reason (this also checks to make sure the object you send through is not null) you will get a null back; which is fine because you're mapping to a nullable datetime.
To use this you would do something like:
OptionExpiration = dr["OPTION_EXPIRATION"].AsNullableDateTime();
No mess, easy to understand what is happening, abstracting away the clutter, and highly reusable on other parts of your solution.
I've made an UltraGrid with Infragistics where I have a column of Datetime type with the format HH:mm.
Normally the column is filled with a value like : "15:13". I can edit it and set what I want then save. But if I delete the field it looks like that : "_ : _" then I save my table, I get back an exception "Specified cast is not valid".
This is because I'm trying to save a value which is not set. I would like to know how to handle this exception.
I tried to compare the fiel to "null" but it does not work.
var newDuration = (DateTime)row.GetCellValue(3);
if (newDuration == null)
{
MessageBox.Show("Please set all the fields.");
}
The dataType of the column is System.DateTime, I set the default value to DB (DBNull) and AllowDBNull is Default.
There are two ways to fix the issue:
display a message to the user to ask him to set a value
If the field is empty, set a default value like 00:00
Ask me if you need more info. Thanks !
Typical pattern to try to get value of wanted type without being sure is
var value = someOtherValue as SomeType;
if (value != null)
{
... // value is a correct SomeType here
}
This works for reference types. In case of structures (DateTime is a structure), which are value types, you'll have to check the type prior
var value = row.GetCellValue(3);
if(value is DateTime)
{
var dateTime = (DateTime)value;
... // dateTime is a valid DateTime here
}
My answer doesn't explain why you have the problem, but shows how to avoid having it (which may not be a good idea, but it seems you want that).
If your value can be DBNull, then simply check for it:
var value = row.GetCellValue(3);
if(value != DBNull.Value)
{
var dateTime = (DateTime)value; // it must work now
...
}
Actually I did this :
try
{
newDuration = (DateTime)row.GetCellValue(3);
}
catch
{
row.SetCellValue(3, new DateTime());
newDuration = (DateTime)row.GetCellValue(3);
}
And it works... Thanks all for your help, I will use what you told in my future dev' !
At the wingrid there is a specific event for handling this errors, its datacellerror quite useful and no need of anything else, hope this its helpfull for someone
I have a Linq to SQL query very similar to the following:
var result = (from shareclass in database.ShareClassInfo
where shareclass.Id == ID
select new ShareClass
{
IsOnlineListing = shareclass.IsOnlineListing
}
);
var list = result.ToList();
When I try to create a list from the results I get the following error:
The null value cannot be assigned to a member with type System.Boolean which is a non-nullable value type.
The reason for this is that IsOnlineListing is a bool, but the field in the database is null. So I'm effectively trying to assign a value type with a null value (which is impossible).
I think the solution to this is to make IsOnlineListing a nullable type, but I'm a little confused why I was let do this in the first place. I mean, the database field is defined as a [bit] NULL field. I thought the compiler would be smarter than to let me assign null value to a non-nullable type, or at least it would warn me about it.
So what I'm wondering, is if this is the correct solution? Is there another way to do this? Why wasn't the compiler able to tell me that this is or could be a problem?
you need to change your declaration of IsOnlineListing
From
bool IsOnlineListing;
To
bool? IsOnlineListing;
Or do something like this
var result = (from shareclass in database.ShareClassInfo
where shareclass.Id == ID
select new ShareClass
{
IsOnlineListing = shareclass.IsOnlineListing.HasValue ?
shareclass.IsOnlineListing.Value : false;
}
);
var list = result.ToList();
You can use a nullable type.
I have asp.net form with C#, where is I am taking user information to insert in the database as usual by using Linq. well. Where as I am taking Date of birth also from the user, but if user skip to fill date text box from ui, then I am getting date like '01/01/0001' something like this, which certainly database security would not allow to store it.
So I need to check somewhere in my code that it is null or in this (above given) format. If it is null or in format '01/01/0001' then what exactly I have to do? I don't have any default
value for dates.
So what is the standard way to handle if date is null (but not mandatory).Please guide me. So many times I found myself in trap while handling null for various types.
Edited
see what i did seems it working here. but i don't think so this is standard way:
DateTime? otxtDOB = new DateTime();
if (!string.IsNullOrEmpty(DOB))
{
if (Convert.ToDateTime(DOB) != DateTime.MinValue)
{
otxtDateOfPurchese = Convert.ToDateTime(Convert.ToDateTime(DOB).ToString("dd-MMM-yyyy"));
}
else
{
otxtDOB = null;
}
}
Please confirm me is this right way ?
Making the date property Nullable (i.e. a "DateTime?") should allow it to actually be null if the user hasn't set it. (And provided your database column will allow nulls, it can be stored as null in the database)
Otherwise it's going to default to DateTime.MinValue which is what you're seeing here. And you'll have to explicity test for DateTime.MinValue when adding to the database.
DateTime is a value type (like a number), so you can't assing a null value to it. Mane people use DateTime.MinValue or DateTime.MaxValue instead, but I prefer to use nullable types:
DateTime? nullableDate;
dateSample.Value = null;
you can do some thing like this C# have some features like nullable type you can make use of
this it will save you some piece of code it will be more robust too.
Public int InsertData(int? ouId)
{
chkValue = ouId.HasValue ? ouId.Value : 0;
}
You have the option of using Nullable<DateTime> (alias DateTime?). This makes you able to handle the date as null throughout your application.
However, personally I am not to found of nullables and would prefer this second path: You can use DateTime.MinValue (which is 01/01/0001) as a meaningful constant in your application and the check for DateTime.MinValue in your data access layer.
The database, if it is an SQL Server and the field is of type smalldatetime, would overflow and throw an exception if you tried to save DateTime.MinValue. Null however, may well be stored in the database for any type.
This is how you can parse your strings into nullable types:
private delegate bool TryParseDelegate<T>(string s, out T t);
private static T? TryParseNullable<T>(string s, TryParseDelegate<T> tryParse) where T : struct
{
if (string.IsNullOrEmpty(s))
return null;
T t;
if(tryParse(s, out t))
return t;
return null;
}
with usage:
var nullableDateTime = TryParseNullable<DateTime>("01/01/0001", DateTime.TryParse);
use
DateTime dt;
if(DateTime.TryParse(DatetImeValue.Tostring(),dt)) // datetimevalue is your db value
{
datetimeproperty = dt; // in your class declare it as DateTime? datetimeproperty
}
else
{
datetimeproperty = null;
}
While displaying check for null, if its null set it empty.
[Update]
Do one thing, Keep the property nullable. In your database. Set field to allow null and in the parameter user #DateTimeParam = null.
OR A QUICK WORKAROUND MAKE THE DATABASE FIELD AND PARAMETER VARCHAR INSTEAD OF DATETIME, IN PARAMETER PASS DATETIMEVALUE.TOSHORTDATESTRING() AND ALSO CHECK IF USER SKIPS
PUT STRING.EMPTY IN PARAMETER. IN THIS MANNER IT WILL BE EASY TO YOU TO DISPLAY DATE AND TIME. YOU NEED NOT CAST OR WIPE OFF THE TIME PART IF YOU DO NOT NEED IT
obj.BirthDate = Convert.ToDateTime(string.IsNullOrEmpty(txtBirthDate.Text.ToString()) ? System.Data.SqlTypes.SqlDateTime.MinValue.Value : Convert.ToDateTime(txtBirthDate.Text.ToString()));
You can use this while passing to database.
object datetimeObj = null;
if (datetimefromUI == DateTime.MinValue) // This is put in the DateTime object by default
datetimeObj = DBNull.Value;
else
datetimeObj = datetimefromUI;
// Post datetimeObj to parameter in database...