Is where a way to check if DateTime is null in linq expression? I've IEnumeable method where I'm returning data from database
return _requestRepository.ExecuteProcReader(
myRequest,
new SqlParameter("#userName", user)).Select(items => new Feed
{
Id = (int)items[0],
Title = items[1].ToString(),
Body = items[2].ToString(),
Link = items[3].ToString(),
PubDate = (DateTime) items[4]
});
And items[4] is a datetime which can be null in database. So, how can check something like
if(items[4] is DateTime)
{
PubDate = (DateTime) items[4]
}
One more option would be to declare PubDate as nullable inside class Feeddeclaration.
Like this:
class Feed {
public DateTime? PubDate {get;set;}
...
}
This will expose truth from database into data access layer and shift your null checks one level up.
See: Nullable types in c#
May be you can use ternary operator here.
return _requestRepository.ExecuteProcReader(myRequest,new SqlParameter("#userName", user)).Select(items => new Feed
{
Id = (int)items[0],
Title = items[1].ToString(),
Body = items[2].ToString(),
Link = items[3].ToString(),
PubDate = ((DateTime)items[4]).HasValue ? (DateTime) items[4] : DateTime.Now
//Or any date you want to use
});
You should also check for DBNull.Value when getting data from a database.
Here's what I'll do :
PubDate = (item[4] == null || item[4] == DBNull.Value ? DateTime.Now : (DateTime)item[4])
If you have multiple fields that can be NULL in database, you can put it in an extension method as :
public static object GetDBValue(this object value, object defaultValue)
{
return value == null || value == DBNull.Value ? defaultValue : value;
}
And call it with :
PubDate = (DateTime)date1.GetDBValue(DateTime.Now);
Related
EDIT:
Thanks to everyone who replied! I appreciate all of your answers :)
So I have a class with the following constructor:
public Transaction(DataRow row)
{
LastName = row.Field<string>("LastName");
FirstName = row.Field<string>("FirstName");
MI = row.ItemArray[3].ToString()[0];
ContactNumber = row.ItemArray[4].ToString();
Hours = int.Parse(row.ItemArray[5].ToString());
CheckIn = (DateTime)row.ItemArray[6];
roomNumber = int.Parse(row.ItemArray[9].ToString());
//Paid = row.Field<int>("Paid");
//TotalBill = row.Field<int>("TotalBill");
}
Notice I have 2 of them commented out with /'s That's because if I don't they return null values even if I try ''row.Field([Whatever]).GetValueOrDefault()'', it still comes out null and my constructor returns null. I also have my DB set with default values so IDK what's wrong.
Anyone got a work around? :)
The DataRow class has a method that is called IsNull and that could receive the column name.
Just combine it with the conditional operator
Paid = row.IsNull("Paid") ? 0 : row.Field<int>("Paid");
the same is true for all other fields that could contain a null value.
Just check for null first and supply a default value:
public Transaction(DataRow row)
{
LastName = row.Field<string>("LastName");
FirstName = row.Field<string>("FirstName");
MI = row.ItemArray[3].ToString()[0];
ContactNumber = row.ItemArray[4].ToString();
Hours = int.Parse(row.ItemArray[5].ToString());
CheckIn = (DateTime)row.ItemArray[6];
roomNumber = int.Parse(row.ItemArray[9].ToString());
Paid = row.Field<int?>("Paid") ?? 0;
TotalBill = row.Field<int?>("TotalBill") ?? 0;
}
See the ?? Operator (C# Reference) page on MSDN for further information on the ?? operator.
You can simply use the Nullable type and GetValueOrDefault method or use null coalescing operator.
Paid = row.Field<int?>("Paid").GetValueOrDefault()
or
Paid = row.Field<int?>("Paid") ?? 0
In both cases Paid will have a value of 0, you can change if you want.
Create your own little function that does a simple check.
Along the lines of:
public integer GetNumber (object val)
{
if (IsNumeric (val))
{
return val;
} else
{
return 0;
}
}
I'm not fantastic with C#, but that should give you an idea. Sorry about formatting, I'm on a phone which doesn't help at all.
There are some value contain in my database branch column for example "B01",
I am trying to set my branch column back to null value
I had tried
string.Empty
String.Empty
""
null
DBNull.value
Noted* all the method able to set my value back to "" but not my expected result, my expected result is my column back to "NULL" but not ""
if (ddlBranches.SelectedIndex > 0 && ddlLocation.SelectedItem.Text.ToUpper() == "BRANCH")
{
drUpdProb["Branch"] = ddlBranches.SelectedValue.ToString();
drUpdProb["BranchAbbr"] = ddlBranches.SelectedItem.Text;
}
else
{
drUpdProb["Branch"] = DBNull.value;
drUpdProb["BranchAbbr"] = DBNull.value;
}
Try something like the following create a parameter to assign values
cmd.Parameters.AddWithValue("#Branch", drUpdProb["Branch"] ?? (object)DBNull.Value);
cmd.Parameters.AddWithValue("#BranchAbbr", drUpdProb["BranchAbbr"] ?? (object)DBNull.Value);
I am trying to insert a DateTime value in sqlserver using linq. The DateTime value in the csharp side may be null. The corresponding field in sqlserver is a nullable datetime field. Following is my code:
using (var dataContext = GetDataContext())
{
DateTime dateTime;
var combinedWorkBasket = new CombinedWorkBasket()
{
FirstName = combinedWorkbasketData.FirstName,
LastName = combinedWorkbasketData.LastName,
Address1 = combinedWorkbasketData.Address1,
RetirementDate = Convert.ToDateTime(combinedWorkbasketData.RetirementDate),
};
dataContext.CombinedWorkBaskets.InsertOnSubmit(combinedWorkBasket);
dataContext.SubmitChanges();
}
When combinedWorkbasketData.RetirementDate happens to be null, which is a string value, which could be a valid date or null, then sqlserver throws error saying the date should be within range. When combinedWorkbasketData.RetirementDate happens to be null, Convert.ToDateTime(combinedWorkbasketData.RetirementDate) translates to some invalide data value. I tried the following, still same issue.
RetirementDate = DateTime.TryParse(combinedWorkbasketData.RetirementDate, out temp) ? Convert.ToDateTime(combinedWorkbasketData.RetirementDate) : Convert.ToDateTime(null)
I simply want to accomplish the following: When combinedWorkbasketData.RetirementDate is a valid date insert RetirementDate, otherwise don't insert it but insert other values such as Firstname etc
Thanks
You might want to use a nullable data type, but this helps only if your database permits null values in the RetirementDate column. In addition, you must make the RetirementDate field in class CombinedWorkBasket nullable, too.
using (var dataContext = GetDataContext())
{
DateTime? dateTime;
var combinedWorkBasket = new CombinedWorkBasket()
{
FirstName = combinedWorkbasketData.FirstName,
LastName = combinedWorkbasketData.LastName,
Address1 = combinedWorkbasketData.Address1,
RetirementDate = combinedWorkbasketData.RetirementDate != null ?
Convert.ToDateTime(combinedWorkbasketData.RetirementDate) : null;
};
dataContext.CombinedWorkBaskets.InsertOnSubmit(combinedWorkBasket);
dataContext.SubmitChanges();
}
The problem is that datetime does not holds null value but it holds minimum time i.e. some thing like this. '1/1/0001 12:00:00 AM'.
Instead of directly passing the date time try using
DateTime.MinValue== Convert.ToDateTime(combinedWorkbasketData.RetirementDate)?Null:Convert.ToDateTime(combinedWorkbasketData.RetirementDate)
I have not tested the code use it as reference u might be needing some refinement.
I think RetirementDate must be of nullable type for Entity framework to insert DBNull.
So make it like
public class CombinedWorkBasket
{
// other fields
public DateTime? RetirementDate { get; set; }
}
Then try assigning Null as per logic with associated column as "Allow Null" in database.
Hopefully it will insert null.
Howsit!
I encounter an error when i get a null value in my datareader.
public List<Complaint> View_all_complaints()
{
csDAL objdal= new csDAL();
List<Complaint> oblcomplist=new List<Complaint>();
using( IDataReader dr=objdal.executespreturndr("View_all_complaints"))
{
while (dr.Read())
{
Complaint objcomp= new Complaint();
populate_reader(dr,objcomp);
oblcomplist.Add(objcomp);
}
}
return oblcomplist;
}
public void populate_reader(IDataReader dr, Complaint objcomp)
{
objcomp.ref_num = dr.GetString(0);
objcomp.type = dr.GetString(1);
objcomp.desc = dr.GetString(2);
objcomp.date = dr.GetDateTime(3);
objcomp.housenum = dr.GetInt32(4);
objcomp.streetnum = dr.GetInt32(5);
objcomp.status = dr.GetString(6);
objcomp.priority = dr.GetString(7);
objcomp.cid = dr.GetInt32(8);
if (!dr.IsDBNull(9))
{
objcomp.resolved_date = dr.GetDateTime(9);
}
}
in sql resolved date allows null values, this is so because only when a complaint has been resolved , it must reflect that date otherwise it should be null.
if dr.getdatetime(9) is null then it must just set a string saying "Not Resolved"
please help!
You haven't shown what your Complaint type looks like, but basically you'll want to make sure that its resolved_date is of type DateTime? aka Nullable<DateTime>. That allows you to model a missing value elegantly.
As for displaying it - you haven't shown anything about where you display the data, but you'd want something like:
string text = complaint.ResolvedDate.HasValue ? complaint.ResolvedDate.ToString()
: "Not Resolved";
(I've changed this to use a property with the idiomatic name at the same time...)
IDataReader has a "IsDBNull" method, that should be called before calling GetXXX(), in case your value is not nullable.
For example:
objcomp.date = dr.GetDateTime(3);
should be:
objcomp.date = dr.IsDBNull(3) ? DateTime.MinValue : dr.GetDateTime(3);
Let's say I have the following XML:
<Account>
<AccountExpirationDate>6/1/2009</AccountExpirationDate>
</Account>
I want to use LINQ to XML to parse this into an object I'll call Account:
public class Account {
public DateTime? AccountExpirationDate { get; set; }
}
This is the C# code I've tried, but it won't let me use null:
var accountSettings =
from settings in templateXML.Descendants("Account")
select new Account {
AccountExpirationDate =
string.IsNullOrEmpty(settings.Element("AccountExpirationDate").Value)
? DateTime.Parse(settings.Element("AccountExpirationDate").Value)
: null
};
Is there a way for me to only assign AccountExpiration a date if the element exists in the XML? In my business logic it is acceptable for the value to be null. Thanks!
var accountSettings =
from settings in templateXML.Descendants("Account")
select new Account {
AccountExpirationDate =
string.IsNullOrEmpty((string)settings.Element("AccountExpirationDate"))
? (DateTime?)null
: DateTime.Parse(settings.Element("AccountExpirationDate").Value)
};
You can just use:
from settings in templateXML.Descendants("Account")
let el = settings.Element("AccountExpirationDate")
let el2 = (el == null || string.IsNullOrEmpty(el.Value)) ? null : el
select new Account {
AccountExpirationDate = (DateTime?)el2
};
there is a conversion operator that works this magic using standard xml datetime formatting, and which returns null if the element doesn't exist (note I don't read .Value).
Try:
var accountSettings = from settings in templateXML.Descendants("Account")
where settings.Element("AccountExpriationDate") != null
&& !String.IsNullOrEmpty(settings.Element("AccountExpriationDate").Value)
select new Account
{
AccountExpirationDate = DateTime.Parse(settings.Element("AccountExpirationDate").Value)
};
For a more readable syntax and if you need such a check multiple times, you could use extension methods:
public static DateTime? ToDateTime(this Element e)
{
if (e == null)
return null;
if (string.IsNullOrEmpty(e.Value))
return null;
else
return DateTime.Parse(e.Value);
}