Unable to catch if a list item name is missing - asp.net-mvc

I have the following code which groupBY my table and select the count based on the model name:-
var IT360Counts = entities.Resources.Where(a => String.IsNullOrEmpty(a.ASSETTAG) && (a.SystemInfo.ISSERVER == true))
.GroupBy(a => a.SystemInfo.MODEL.ToLower())
.Select(g => new
{
Action = g.Key.ToLower(),
ItemCount = g.Count()
}).ToLookup(a => a.Action);
Then i will referecne the var content such as :-
IT360RouterNo = IT360Counts["router"] == null ? 0 : IT360Counts["router"].SingleOrDefault().ItemCount,
The above will work well, unless when the first query does not have any router, then the second statement will always return null exception. so my question is weather there is a way to catch if IT360Counts["router"] exists sor not ?
Thanks

This will happen when IT360Counts["router"] is not null but an empty list. In that case IT360Counts["router"].SingleOrDefault() will return null, so when accessing its ItemCount property you will get a null exception.
This happens because the indexer in the Lookup returns an empty list when the key is not found. See remarks section in msdn. Try checking if the lookup contains the key, IT360Counts.Contains("router"). This way you can do:
IT360RouterNo = IT360Counts.Contains("router") ? IT360Counts["router"].SingleOrDefault().ItemCount : 0,
As a side note, have you also considered using ToDictionary instead of ToLookup? The dictionary key would be your Action and the value the ItemCount, so when retrieving the values you just get the value in the dictionary for a key like "router". If you are you always doing .SingleOrDefault().ItemCount and never expect more than one item with the same Action, you may be better using a dictionary.
For the sake of completion this idea would be:
var IT360Counts = entities.Resources.Where(a => String.IsNullOrEmpty(a.ASSETTAG) &&(a.SystemInfo.ISSERVER == true))
.GroupBy(a => a.SystemInfo.MODEL.ToLower())
.Select(g => new
{
Action = g.Key.ToLower(),
ItemCount = g.Count()
}).ToDictionary(a => a.Action, a => a.ItemCount);
IT360RouterNo = IT360Counts.ContainsKey("router") ? IT360Counts["router"] : 0,
Hope it helps!

Related

Include () method not loading in some conditions

I have the following EF query :
var result = (from t in context.Tickets.Include("Priority").Include("Status")
where t.TicketOpenBy.Id == user.Id
select t).Include(t => t.TicketOpenBy);
I also try
context.Tickets.Where(t => t.TicketOpenBy.Id == userId).Include("Priority").Include("Status").Include("TicketOpenBy");
When i receive the list, for each row, the object "TicketOpenBy" has all fields null.
But when i change the "where" with this condition :
"where t.TicketOpenBy.Id != user.Id"
I receive my object with all properties included.
I don't understand this behaviour. What am I doing wrong?

Cannot compare in linq

I am trying to get the result of the user logged in but receiving this error :
"Cannot compare elements of type 'System.Linq.IQueryable`1'. Only
primitive types, enumeration types and entity types are supported. "
Here is the query I'm applying in my index action:
var viewModel = new PointsViewModel();
viewModel.Point = db.Point.ToList();
viewModel.Redeem = db.Redeem.ToList();
TempData["UserPoints"] = null;
var usrname = (from a in db.Instructors
where a.Email == User.Identity.Name
select new { a.PersonID });
if (usrname.Count().Equals(0))
{
TempData["UserPoints"] = "You have not earn any points yet.";
return View();
}
viewModel.instructor = db.Instructors
.Where(i => i.PersonID.Equals(usrname))// if I directly insert id here then it works properly but I don't want direct inserts
.Single();
PopulateAssignedPointData(viewModel.instructor);
return View(viewModel);
Please help me with this please...I am unable to find any solution on google
It's because you're passing usrname as a parameter to another query. usrname is a query, not a value, so you need to retrieve a value from the query (in this case, by using First(), but you could just as easily use Single() if you like) before you can use it as a parameter in another query. I would recommend the following changes:
if (!usrname.Any())
{
TempData["UserPoints"] = "You have not earn any points yet.";
return View();
}
var personId = usrname.First();
viewModel.instructor = db.Instructors
.Where(i => i.PersonID.Equals(personId))
.Single();
I also changed usrname.Count().Equals(0) to !usrname.Any() as it is more idiomatic (it will use the exists keyword in SQL, rather than count)
Try to use this:
viewModel.instructor = db.Instructors
.Where(i => usrname.Any(u => u.PersonID == i.PersonID))
.Single();

LINQ Union Allways returning empty sets

I'm doing some LINQ to look for keywords typed in a textbox. Each keyword ends with ";" and i need to look for itens that contain at least one of those keys.
I thought that i would be able to achieve this with this loop
IEnumerable<ItemFAQ> allResults = null;
foreach (var item in termosPesquisaIsolados)
{
IEnumerable<ItemFAQ> tempResults =
_dbHelpDesk.ItemFAQ
.Where(x => x.DescricaoResposta.Contains(item) || x.TituloTopico.Contains(item))
.ToList()
.Select(x => new ItemFAQ
{
IdPergunta = x.IdPergunta,
TituloTopico = x.TituloTopico,
DescricaoResposta = x.DescricaoResposta.Substring(0, 100)
});
if (allResults != null)
allResults = allResults.Union(tempResults);
else
allResults = tempResults;
}
At first iteration tempResult returns in a test 3 elements then it passes then to allResult, everything ok with that.
The second iteration, tempResult returns 2 ocurrences... then according to code allResult should receive the Union of AllResult and the TempResults, but no matter what i do, when i use the Union clause the result in an Empty Set.
So 3 + 2 = 0 at the end after using Union.
Do you guys can see the mistake at this peace of code or know some issues that could lead to this error ?
Thanks for your time.
try replacing this line:
allResults = allResults.Union(tempResults);
with:
allResults = allResults.Union(tempResults).ToList();

how can I use FirstOrDefault()?

I have this code and I want to set a value to Viewdate when the expression returns no data:
ViewData["Fix"] = db.PreStatusViws.Where(c => c.LkpNameFix == "1").FirstOrDefault().NumCoefficientFix;
can I set zero or a "Text" for that? I no, what can I do?!
note: FirstOrDefault(null) cause an error.
If I understand your question correctly, the following code should solve your problem:
var p = db.PreStatusViws.Where(c => c.LkpNameFix == "1").FirstOrDefault();
if(p != null)
ViewData["Fix"] = p.NumCoefficientFix;
else
ViewData["Fix"] = 0;
Default will return the default for the data type. If the data type in that place is a reference type (e.g. string) the default value will always be null, and therefore the following .NumsCoefficientFix member will throw a NullReferenceException.
The default value is built into .NET and not changeable, and is always given if the result set contains no value.
#Mikey has already given the code sample in his answer that I would suggest.
If you first select the numeric column, FirstOrDefault will work as you intend, returning either a value or 0 (the default for numeric types):
ViewData["Fix"] = db.PreStatus
.Select (c => c.NumCoefficientFix)
.FirstOrDefault (c => c.LkpNameFox == "1");
If NumCoefficientFix is a nullable type, then use the ?? operator to convert the null into 0:
ViewData["Fix"] = db.PreStatus
.Select (c => c.NumCoefficientFix)
.FirstOrDefault (c => c.LkpNameFox == "1") ?? 0;
Selecting the NumCoefficientFix first is also (slightly) more efficient for LINQ-to-database queries, in that the SQL generated will select only that column.
You just have to select your NumCoefficientFix property before calling FirstOrDefault:
ViewData["Fix"] = db.PreStatusViws
.Where(c => c.LkpNameFix == "1")
.Select(c => c.NumCoefficientFix)
.FirstOrDefault();`
Or in LINQ notation:
ViewData["Fix"] = (from c in db.PreStatusViws
where c.LkpNameFix == "1"
select c.NumCoefficientFix
).FirstOrDefault();

Returning a list of keys with ModelState errors

How can I return a list/array of all keys that have an error?
I have tried to do the below, but it says I can't have that sort of expression for some reason.
ModelState.ToList(item => item.Value.Errors.Count > 0)
var errors = from modelstate in ModelState.AsQueryable().Where(f => f.Value.Errors.Count > 0) select new { Title = modelstate.Key };
Count is a method. You need ()s after is. But I'd prefer Any, anyway:
from item in ModelState
where item.Value.Errors.Any()
select item.Key

Resources