Nullable <int> </int>上的空例外

时间:2013-07-18 22:22:49

标签: asp.net asp.net-mvc

我的asp.net mvc web应用程序中有以下模型类:

public class SecurityRoleGroupAssign
{
    public  IEnumerable<TechnologyType> TechnologyType {get; set;}
    public  IEnumerable<PermisionLevel> PermisionLevel {get; set;}
    public SecurityRole SecurityRole { get; set; }
    public Nullable<int> rackPermisionLevel { get; set; }
    public Nullable<int> serverPermisionLevel { get; set; }
    public Nullable<int> routerPermisionLevel { get; set; }
    public Nullable<int> virtualMachinePermisionLevel { get; set; }
    public Nullable<int>  switchPermisionLevel { get; set; }
}

但是当我试图填充这个课程时,我得到了一个空的例外: -

public SecurityRoleGroupAssign populateSecurityRolePermisionLevelAssign(int RoleID)
{
    SecurityRoleGroupAssign c = new SecurityRoleGroupAssign
    {
        SecurityRole = FindAllRole(RoleID),
        PermisionLevel = tms.PermisionLevels.ToList(),
        TechnologyType = tms.TechnologyTypes.ToList(),
        serverPermisionLevel = tms.SecurityroleTypePermisions
         .Where(a=>a.SecurityRoleID == RoleID)
         .Where(a2=>a2.TechnologyType.Name.ToLower() == "server")
         .SingleOrDefault().PermisionLevelID,
        rackPermisionLevel = tms.SecurityroleTypePermisions
         .Where(a => a.SecurityRoleID == RoleID)
         .Where(a2 => a2.TechnologyType.Name.ToLower() == "rack")
         .SingleOrDefault().PermisionLevelID,
        virtualMachinePermisionLevel = tms.SecurityroleTypePermisions
         .Where(a=>a.SecurityRoleID == RoleID)
         .Where(a2=>a2.TechnologyType.Name.ToLower() == "virtual machine")
         .SingleOrDefault().PermisionLevelID,
        routerPermisionLevel = tms.SecurityroleTypePermisions
         .Where(a=>a.SecurityRoleID == RoleID)
         .Where(a2=>a2.TechnologyType.Name.ToLower() == "router")
         .SingleOrDefault().PermisionLevelID,
        switchPermisionLevel = tms.SecurityroleTypePermisions
         .Where(a => a.SecurityRoleID == RoleID)
         .Where(a2 => a2.TechnologyType.Name.ToLower() == "switch")
         .SingleOrDefault().PermisionLevelID
    };
    return c;
}

2 个答案:

答案 0 :(得分:3)

问题是如果不存在任何项目,SingleOrDefault将返回null(对于引用类型)。因此,每当您致电.SingleOrDefault().PermisionLevelID时,您都有空引用异常的危险。你可以通过在所选结果之后放置.SingleOrDefault()来解决这个问题 - 例如(... select p.PermissionLevelID).SingleOrDefault()

试试这个:

var permissions = tms.SecurityroleTypePermisions.Where(a => a.SecurityRoleID == RoleID);
SecurityRoleGroupAssign c = new SecurityRoleGroupAssign
{
    SecurityRole = FindAllRole(RoleID),
    PermisionLevel = tms.PermisionLevels.ToList(),
    TechnologyType = tms.TechnologyTypes.ToList(),
    serverPermisionLevel = 
        (from p in permissions
         where p.TechnologyType.Name.ToLower() == "server"
         select p.PermisionLevelID)
        .SingleOrDefault(),
    rackPermisionLevel = 
        (from p in permissions
         where p.TechnologyType.Name.ToLower() == "rack"
         select p.PermisionLevelID)
        .SingleOrDefault(),
    virtualMachinePermisionLevel = 
        (from p in permissions
         where p.TechnologyType.Name.ToLower() == "virtual" 
         select p.PermisionLevelID)
        .SingleOrDefault(),
    routerPermisionLevel = 
        (from p in permissions
         where p.TechnologyType.Name.ToLower() == "router")
         select p.PermisionLevelID
        .SingleOrDefault(),
    switchPermisionLevel =
        (from p in permissions
         where p.TechnologyType.Name.ToLower() == "switch"
         select p.PermisionLevelID
        .SingleOrDefault()
};

或者更好:

var permissions = tms.SecurityroleTypePermisions
                     .Where(a => a.SecurityRoleID == RoleID)
                     .ToLookup(a => a.TechnologyType.Name.ToLower(),
                               a => a.PermisionLevelID);
SecurityRoleGroupAssign c = new SecurityRoleGroupAssign
{
    SecurityRole = FindAllRole(RoleID),
    PermisionLevel = tms.PermisionLevels.ToList(),
    TechnologyType = tms.TechnologyTypes.ToList(),
    serverPermisionLevel = permissions["server"].SingleOrDefault(),
    rackPermisionLevel = permissions["rack"].SingleOrDefault(),
    virtualMachinePermisionLevel = permissions["virtual"].SingleOrDefault(),
    routerPermisionLevel = permissions["router"].SingleOrDefault(),
    switchPermisionLevel = permissions["switch"].SingleOrDefault()
};

答案 1 :(得分:2)

.SingleOrDefault():

  

返回序列的唯一元素,如果是,则返回默认值   序列是空的;如果有更多,此方法会抛出异常   比序列中的一个元素。

serverPermisionLevel = tms.SecurityroleTypePermisions.Where(a=>a.SecurityRoleID == RoleID).Where(a2=>a2.TechnologyType.Name.ToLower() == "server").SingleOrDefault().PermisionLevelID;

这里的问题是.SingleOrDefault();调用返回了默认的“null”值。当您尝试在该空引用上调用PermissionLevelID时抛出该错误。

您可以将其更改为:

 serverPermisionLevel = tms.SecurityroleTypePermisions
.Where(a=>a.SecurityRoleID == RoleID)
.Where(a2=>a2.TechnologyType.Name.ToLower() == "server")
.Select(r => r.PermissionLevelID).SingleOrDefault();

这样,当.SingleOrDefault实际返回null时,你的可为空的int将被填充,或者如果有的话,将填充PermissionLevelId的实际值。