Reputation: 493
I am getting this error:
"Index was outside the bounds of the array."
By using this LINQ query
I want, if A.LogOutTime is returning null then display "Unknown".
var listItems = (from A in data orderby A.FirstName
select new {
Action = "Logout",
UserName = A.FirstName + " " + A.SurName,
ID = A.Id,
AccessDate = (A.LogOutTime ?? "Unknown")
.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[0],
AccessTimeFrame = (A.LogOutTime ?? "Unknown")
.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[1]
+ " " + (A.LogOutTime ?? "Unknown")
.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[2],
Comment = "Never delete this Archive"
}).Distinct();
How can I solve this?
Upvotes: 1
Views: 2868
Reputation: 37299
The problem is that when the A.LogOutTime
is null
you place the string "Unknown"
which you afterwards split by " "
at go to some indexes of the returned IEnumerable
. Those indexes do not exist so you get that error.
I suggest that you do something like the following:
let
so you do not repeat the split each time. Use the C# 6.0 ?.
when splitting to avoid a NullReferenceException
(in the case that the LogOutTime
is null the sections
will also still be null)LogOutTime
is null
and if so assign the "Unknown"
. If it isn't use the result of the split as neededElementAtOrDefault(n)
so you do not access an index that does not existSo:
var listItems = (from A in data
orderby A.FirstName
let sections = A.LogOutTime?.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
select new {
Action = "Logout",
UserName = A.FirstName + " " + A.SurName,
ID = A.Id,
AccessDate = A.LogOutTime == null ? "Unknown" : sections.ElementAtOrDefault(0),
AccessTimeFrame = A.LogOutTime == null ? "Unknown" : (sections.ElementAtOrDefault(1) + " " +
sections.ElementAtOrDefault(2)),
Comment = "Never delete this Archive" }
).Distinct();
Also by checking that LogOutTime
is not null
I assume it is a string
. Instead save it as a DateTime
and then you wont have the problems of splitting and accessing some index that does not exist. Use the different properties of DateTime
or the ToString()
overload where you specify a desired format. For more on the matter: Custom Date and Time Format Strings
Upvotes: 1
Reputation: 2562
Use the "let" keyword to split the parts of the log out time only once. Then check the length of the parts while calculating AccessTimeFrame.
var listItems = (from A in data
let logOutTimeParts = (A.LogOutTime ?? "Unknown").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
orderby A.FirstName
select new
{
Action = "Logout",
UserName = A.FirstName + " " + A.SurName,
ID = A.Id,
AccessDate = logOutTimeParts[0],
AccessTimeFrame = logOutTimeParts.Length >= 3 ? logOutTimeParts[1] + " " + logOutTimeParts[2] : "",
Comment = "Never delete this Archive"
}
).Distinct();
Upvotes: 1