NULL值处理细节
- 2020年8月24日
- 4分钟阅读
本主题描述使用’null’值的细节,以及在编写条件时应如何对待它们。
考虑以下示例。该员工持久化类暴露了两个属性-名字和经理。名称是指定员工姓名的字符串属性。如果当前对象不代表经理,则经理是引用Employee对象的引用属性。如果当前雇员是经理,则该属性包含空引用。
public class Employee : XPObject {
public string Name {
get { return fName; }
set { SetPropertyValue(nameof(Name), ref fName, value); }
}
string fName;
public Employee Manager {
get { return fManager; }
set { SetPropertyValue(nameof(Manager), ref fManager, value); }
}
Employee fManager;
}
假设一个数据库包含六个Employee对象。
您将获得一项任务,以检索不在指定经理的指导下工作的所有员工(包括经理)。假设这位经理是麦克。您可以尝试使用这样的条件来解决您的任务。
XPCollection<Employee> team = new XPCollection<Employee>();
Employee manager =
Session.DefaultSession.FindObject<Employee>(CriteriaOperator.Parse("[Name] = 'Mike'"));
team.Criteria = CriteriaOperator.Parse("Manager.Oid <> ? And Oid <> ?", manager.Oid, manager.Oid);
int count = team.Count; // Returns 2 (Nathan and Bob)
该代码应返回所有不在Mike监督下工作的员工,Mike本人除外。在我们的示例中,应为John,Nathan和Bob。但是,您看到的结果集合仅包含Nathan和Bob。这是因为约翰没有分配经理。在SQL中,您无法将值与“ null”进行比较。这样的比较不会产生布尔值,而是会产生“未知”值,从而导致结果集为空。由于John没有管理员,因此相应的数据库列为’null’。上面演示的标准试图将“ null”与Mike的标识符进行比较。这样的比较无法正确评估,因此,John从结果集合中省略了。
在编写这样的条件时,您需要显式检查引用属性值是否不是’null’。此外,您不能通过编写“ Manager == NULL”来执行此操作,因为这也将与无法正确评估的“ null”进行比较。要检查值是否为“ null”,必须使用SQL“ is null”谓词。在XPO上下文中,这转换为使用IsNull函数运算符。下面的代码片段演示了可以按预期运行的重写条件。
XPCollection<Employee> team = new XPCollection<Employee>();
Employee manager =
Session.DefaultSession.FindObject<Employee>(CriteriaOperator.Parse("[Name] = 'Mike'"));
team.Criteria = CriteriaOperator.Parse("Iif(IsNull(Manager), Oid, Manager.Oid) <> ?", manager.Oid);
int count = team.Count; // Returns 3 (John, Nathan and Bob)
unt = team.Count; // Returns 3 (John, Nathan and Bob)
演示的条件操作员检查是否设置了Manager属性值,这表示当前处理的员工引用了经理。如果是,则操作员确保所引用的管理员不是Mike。否则,操作员将检查以确保当前处理的员工不是麦克本人。