【发布时间】:2013-01-14 17:00:08
【问题描述】:
我的问题是:如何为navigation property 实现默认的服务器端“过滤器”?
在我们的应用程序中,我们很少真正从数据库中删除任何内容。相反,我们实现了“软删除”,其中每个表都有一个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
}
我在another SO post 中找到了一些如何执行此操作的示例代码,但它需要手动编码 Todo 的每个属性。上述帖子中的代码也返回List,而不是IQueryable。此外,这需要为每个可能的扩展添加方法,这并不酷。
基本上,我正在寻找的是某种方式来定义一段代码,该代码在查询Todos 时被调用,而另一个用于每当查询Tools 时 - 最好能够传递一个定义它是否存在的参数应该返回已删除的项目。这可能是服务器端堆栈上的任何位置 - 无论是在 Web API 方法中、本身还是实体框架的一部分(请注意,过滤包含扩展是 not supported in EF。)
【问题讨论】:
标签: entity-framework asp.net-web-api odata breeze