我的问题是:如何为导航属性实现默认的服务器端“过滤器” ?
在我们的应用程序中,我们实际上很少从数据库中删除任何内容。相反,我们实现了“软删除”,其中每个表都有一个Deleted
位列。如果此列为真,则记录已被“删除”。如果它是假的,它就没有。
这使我们可以轻松地“取消删除”客户端意外删除的记录。
默认情况下,我们当前的 ASP.NET Web API 仅返回“未删除”的记录,除非从客户端deleted
发送参数true
。这个想法是服务的消费者不必担心指定他们只想要未删除的项目。
在 Breeze 中实现同样的功能非常简单,至少对于基础实体来说是这样。例如,这将是经典 Todo 示例的实现,添加一个“已删除”位字段:
// Note: Will show only undeleted items by default unless you explicitly pass deleted = true.
[HttpGet]
public IQueryable<BreezeSampleTodoItem> Todos(bool deleted = false) {
return _contextProvider.Context.Todos.Where(td => td.Deleted == deleted);
}
在客户端,我们需要做的就是...
var query = breeze.EntityQuery.from("Todos");
...获取所有未删除的待办事项,或者...
var query = breeze.EntityQuery.from("Todos").withParameters({deleted: true})
...获取所有已删除的待办事项。
但是,假设 BreezeSampleTodoItem 有一个子集合,用于完成该 Todo 所需的工具。我们将其称为“工具”。工具还实现了软删除。当我们执行一个expand
用于获取 Todo 及其工具的查询时,它将返回所有工具 - “删除”与否。
但是如何在Todo.Tools
展开时默认过滤掉这些记录呢?
我想到每个可能需要扩展的项目都有单独的 Web API 方法,例如:
[HttpGet]
public IQueryable<Todo> TodoAndTools(bool deletedTodos = false, bool deletedTools = false)
{
return // ...Code to get filtered Todos with filtered Tools
}
我在另一个 SO 帖子中找到了一些如何执行此操作的示例代码,但它需要手动编码 Todo 的每个属性。上述帖子中的代码也返回 a List
,而不是IQueryable
. 此外,这需要为每个可能的扩展添加方法,这并不酷。
本质上,我正在寻找某种方法来定义一段代码,该代码在Todos
被查询时被调用,而另一个被查询时被调用Tools
- 最好能够传递一个定义它是否应该返回已删除项目的参数。这可能是服务器端堆栈上的任何位置 - 无论是在 Web API 方法中、本身还是实体框架的一部分(请注意,在 EF 中不支持过滤 Include 扩展。)