CarrotCrop
CarrotCrop

Reputation: 73

How To Handle Null In C#?

Here I am trying to get FormName if exists form column FormName of table MainMenu, but before that I am trying to check whether column FormName consists form name or not by

var chkURL = uow.Repository<MainMenu>().GetAll().Where(x => x.MenuId
== getMenuId && x.IsVisible == 1).Select(x => x.FormName).FirstOrDefault().Any();

but it show an error 'Value cannot be null' even though all parameters (i.e getMenuId , IsVisible = 1 ) consists correct data.

Below is my code

    public string GetChildNodeForm(string menuTitle)
    {
        var getMenuId = uow.Repository<MainMenu>().FindBy(x => x.MenuTitle == menuTitle && x.IsVisible == 1).FirstOrDefault().MenuId;
        var chkURL = uow.Repository<MainMenu>().GetAll().Where(x => x.MenuId == getMenuId && x.IsVisible == 1).Select(x => x.FormName).FirstOrDefault().Any();
        if (chkURL == true)
        {
            return uow.Repository<MainMenu>().FindBy(x => x.MenuId == getMenuId && x.IsVisible == 1).FirstOrDefault().FormName.Trim();
        }
        else
        {
            return null;
        }
    }

Upvotes: 0

Views: 213

Answers (3)

Rafalon
Rafalon

Reputation: 4515

!String.IsNullOrEmpty([linqQueryUntilFirstOrDefault()]) will check if there's a non-empty string matching the conditions without throwing an error if there is no result, and at least it is designed for this exact purpose, which is not the case of .Any() (as it throws null exception when your result is null)

Moreover, I'd advise you to replace the var tag with a bool so people reading the code don't get confused on what you expect the result to be, and then you can remove the == true on your if as chkUrl is already a boolean.

More generally, be careful with .FirstOrDefault().[anything] as .FirstOrDefault() can return null. So either use .FirstOrDefault()?.[anything] or try to write on several lines (there's nothing wrong in doing this, and you may gain in readability)

Upvotes: 1

Rufus L
Rufus L

Reputation: 37020

I think the problem you're encountering in that line is that FirstOrDefault returns the first FormName that matches your condition, or null if none match, and then you try to call Any on that result.

If you were to replace the Where in that line with Any, and remove everything after it, then you would be checking if there were any items that meet the condition:

var chkURL = uow.Repository<MainMenu>().GetAll()
    .Any(x => x.MenuId == getMenuId && x.IsVisible == 1);

However, looking at your code, it appears that you're first looking up the menu id from the menu title, then you're checking again using the menu id to see if there are any items (?), and finally you're trying to get the form name by menu id.

Instead of querying for the same object three times, you can just do it once by simplifying your code to get the FirstOrDefault that matches the menu name, and if that's not null get the FormName, and if that's not null, Trim it and return the trimmed form name (or return null if anything was null along the way):

public string GetChildNodeForm(string menuTitle)
{
    return uow.Repository<MainMenu>().GetAll()
        .FirstOrDefault(x => x.MenuTitle == menuTitle && x.IsVisible == 1)
        ?.FormName?.Trim();
}

Upvotes: 1

KV Prajapati
KV Prajapati

Reputation: 94625

Method FirstOrDefault might returns null so don't use Any() method here.

var formName = uow.Repository<MainMenu>()
               .GetAll()
               .Where(x => x.MenuId == getMenuId && x.IsVisible == 1)
               .Select(x => x.FormName)
               .FirstOrDefault();
if(formName != null ) 
 {
   //TODO
 }

Upvotes: 1

Related Questions