在我的应用程序中,我有跨实体验证逻辑,要求我查看整个更改集,并且我使用BeforeSaveEntities
覆盖执行此操作。
我可以通过检查saveMap
参数来构造正确的逻辑,但如果我发现某些内容无效,我应该怎么做?
如果我抛出一个异常,就像我在BeforeSaveEntity
覆盖中进行单个实体验证一样,整个保存将中止,并将错误报告给客户端。但是有些实体可能是有效的,所以我想保存这些实体并且只中止无效的部分。
由于BeforeSaveEntities
返回saveMap
,我认为我应该能够从更改集中删除无效实体并继续保存有效实体,但是如何将无效部分报告给客户?
是否可以仅对有效实体进行部分保存,同时向客户报告合理的错误,以描述失败的保存部分?
答案 0 :(得分:1)
我不会屏住呼吸等待Breeze的改变,因为我认为你的情况很少见,而且我们不想鼓励它。
但我很奇怪,如果你和我完全不愿意这样做,我就不能再想我会做什么了。我可能会尝试这样的事情。
警告:这是伪代码,我正在解决这个问题。我不建议或保证
创建源自MyCustomEFContextProvider
的自定义EFContextProvider
。
为其提供ErrorEntities
属性以容纳错误对象
覆盖(影子)SaveChanges
方法与委托给基础的另一个方法
public new CustomSaveResult SaveChanges(JObject saveBundle, TransactionSettings transactionSettings = null) { var result = base.SaveChanges(saveBundle, transactionSettings); // learn about CustomSaveResult below return new CustomSaveResult(this.ErrorEntities, result); }
在BeforeSaveEntities
将错误消息传递给您的自定义ErrorEntities
媒体资源
您可以通过EntityInfo
实例访问该属性,如在
中
((MyCustomEFContextProvider) info.ContextProvider).ErrorEntities.Add(new ErrorEntity(info, message));
从SaveMap
中移除无效实体,使其不会包含在实际保存中
让保存继续
覆盖SaveChanges
方法的第二行从标准版本创建CustomSaveResult
的新实例,并将其返回给调用者。
public class CustomSaveResult : SaveResult { public List ErrorEntities; public CustomSaveResult(List errorEntities, SaveResult result){ // copy over everything this.Entities = result.Entities; this.KeyMappings = result.KeyMappings; this.Errors = this.Errors; // and now your error stuff this.ErrorEntities = errorEntities; } }
假设调用者是您的Web API控制器的SaveChanges
方法。好吧,你不需要改变一件事,但你可以通过显式返回你的自定义SaveResult来明确:
readonly MyCustomEFContextProvider _contextProvider = new MyCustomEFContextProvider(); ... [HttpPost] public CustomSaveResult SaveChanges(JObject saveBundle) { return _contextProvider.SaveChanges(saveBundle); }
JSON.Net将很乐意序列化常用材料+您的自定义ErrorEntities
属性(确保使其可序列化!)并将其发送给Breeze客户端。
在Breeze客户端上,您可以在stock Breeze Web API data service adapter上编写自己的变体。你和Breeze版本完全一样。但是,当从服务器处理保存有效负载时,它还会在响应中提取这些额外的“错误实体”材料,并做任何你想做的事情。
我不知道那会是什么,但现在你拥有它。
看看这有多容易? LOL。
答案 1 :(得分:0)
Breeze目前不支持同时保存和返回错误的保存机制。虽然可能这似乎有点巴洛克式。
正如您所指出,您可以
1)在BeforeSaveEntities内部抛出异常并使保存失败。您甚至可以指定导致失败的特定实体或原因。在这种情况下,整个保存将中止。
或
2)从BeforeSaveEntities中的saveMap中删除“bad”项,并仅保存传入的子集。在这种情况下,您正在执行部分保存。
但我们不支持这两者的混合。如果你感觉强烈,请将其添加到Breeze用户语音中,我们可以看到社区的其他成员是否认为这有用。