可空的可选参数

3

我正在使用带有edmx文件和POCO的实体框架4,在asp.net mvc应用程序中。

首先,我有一个人类,它被映射到数据库中的一张表。

public class Person
{
    public Int32 ID{get;set;}
    public string Name{get;set;}
    public Int32? ParentID{get;set;}
}

然后在我的服务层中,我有以下函数来检索所有人。如果提供了parentID,则检索到的人将是具有该parentID的人:

public List<Person> Get(int? parentPersonID = null)
{
    var persons = Repository().GetAll(c => c.ParentID == parentPersonID);
}

最后,Repository()函数返回一个包含以下方法的:
```python ```
public IQueryable<TModel> GetAll(Expression<Func<TModel, bool>> predicate = null)
{
    var result = ObjectSet.AsQuaryable(); //ObjectSet is a ObjectSet<Person> instance
    if (predicate != null)
        result = result.Where(predicate);
    return result;
}

现在的问题是,如果我把parentPersonID设为null传递给服务层,就像Get(null)那样。枚举将不会有任何结果。但是,如果我修改服务层代码如下:
public List<Person> Get(int? parentPersonID = null)
{
    var persons = Repository().GetAll(null);
}

一切都按预期工作。

知道为什么吗?

编辑: 如果我使用以下代码替换服务层函数代码:

var persons = Repository().GetAll(c => c.ParentID.Equals(parentPersonID));

替代:

var persons = Repository().GetAll(c => c.ParentID == parentPersonID);

按预期工作——第一行从数据库检索记录,而第二行不执行此操作。 我仍然好奇在这种情况下Equals()==的区别是什么。

1个回答

2

我猜测这与平等处理方式有关。试试这个:

public List<Person> Get(int? parentPersonID = null) {
    var persons = Repository().GetAll(parentPersonID == null ? 
          c => !c.ParentID.HasValue :                
          c => c.ParentID == parentPersonID);
    ... 
}

这将会将谓词更改为显式的空值检查,当您传入一个parentPersonID参数为null时,而不是只匹配您传入的值。可能有更优雅的表达方式,但至少值得尝试一下。
(我假设,如果您指定parentPersonID参数为null,您想获取拥有空parentPersonID的所有人,而不仅仅是所有人...那将是另一种变化。)

你的假设是正确的,是的。此外,显式检查有效(与Equals()具有相同的结果)。不过我很好奇对于值为null的变量如何处理相等性。后来还发现了这个:https://dev59.com/F3RB5IYBdhLWcg3wQFLu - sTodorov
@sTodorov:是的,我的解决方法就是这样,但稍早一些——所以你最终会得到一个简单的谓词。 - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接