2013-07-18 24 views
0

我有我的asp.net MVC Web應用程序內的下列模型類:空異常可空<int>

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

什麼生產線給你的NRE? –

+3

如果未找到任何值,未經檢查的使用'SingleOrDefault'可以爲您提供空引用異常。 'Single'會拋出一個異常,即集合中沒有匹配的元素,但SingleOrDefault只返回null,此時你正試圖引用一個'null'對象的屬性。換句話說,它可能不是你設置*的屬性,而是你設置它的表達。 – David

+4

字面上,該片段的每一行都可能會引發空引用異常。在您的'SecurityRoleGroupAssign'中添加可空字段絕不會防止類的實例構造出錯。 –

回答

2

.SingleOrDefault():

返回序列的唯一元素,或者如果默認值 序列爲空;如果序列中的一個元素多於 ,則此方法會引發異常。

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

的這裏的問題是,.SingleOrDefault();調用返回默認的「零」值。當您嘗試對該空引用調用PermissionLevelID時,會引發該錯誤。

你可以改變什麼成:

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

這種方式,您可空整數時就會.SingleOrDefault實際上返回null,或與PermissionLevelId的實際價值,如果有一個填補。

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() 
};