重写breeze BeforeSaveEntity()
我遇到了与中讨论的完全相同的问题,答案很好地解释了这一点 我的问题是——我的应用程序有点大,大约有20多个实体需要修改。因此,如果我在datacontext中重写BeforeSaveEntity()并在那里添加所有业务逻辑,那将非常麻烦。正如我在下面的问题中所提到的,我们确实有一个明确的关注点分离(请注意半完成的标题):重写breeze BeforeSaveEntity(),breeze,separation-of-concerns,savechanges,Breeze,Separation Of Concerns,Savechanges,我遇到了与中讨论的完全相同的问题,答案很好地解释了这一点 我的问题是——我的应用程序有点大,大约有20多个实体需要修改。因此,如果我在datacontext中重写BeforeSaveEntity()并在那里添加所有业务逻辑,那将非常麻烦。正如我在下面的问题中所提到的,我们确实有一个明确的关注点分离(请注意半完成的标题): 那么,我是否可以以更有条理的方式来做这件事?我的意思是在一个存储库中为相关实体处理BeforeSaveEntity,同样地,您当然可以在BeforeSaveEntities方
那么,我是否可以以更有条理的方式来做这件事?我的意思是在一个存储库中为相关实体处理BeforeSaveEntity,同样地,您当然可以在
BeforeSaveEntities
方法中进行分支,如的代码所示。在每个if
块中,您可以实例化一个助手类或存储库来处理每个实体类型
一种更基于领域的方法是拥有多个子类EFContextProvider
。每个人都有自己的BeforeSaveEntities
方法来处理自己的域业务规则:
public class AccountManagementContextProvider : EFContextProvider<MyDbContext>
{
Type[] allowedTypes = new Type[] { typeof(Account), typeof(AccountAddress) };
protected override Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap)
{
var illegalTypes = saveMap.Keys.Except(allowedTypes);
if (illegalTypes.Any())
{
throw new ArgumentException("Attempt to save illegal entities");
}
// account management stuff...
}
}
// in a separate file...
public class InventoryContextProvider : EFContextProvider<MyDbContext>
{
protected override Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap)
{
// inventory stuff...
}
}
// etc.
。。。通过以下方式从客户端调用:
谢谢你,史蒂夫。我担心的另一个问题是,用户可能会通过包含不允许保存的类型的对象(例如查找实体)来发送恶意的savebundle。在这种情况下,我们如何进行验证?我的意思是,我们必须通过考虑datacontext中的所有实体来验证捆绑包中的所有内容吗?正确-
BeforeSaveEntities
应该检查saveMap
中的类型,以确保客户端没有发送任何非法的内容。我更新了答案,在AccountManagementContextProvider
中显示了一个例子。您可能需要更深入,确保当前用户只保存允许保存的单个实体。谢谢,我认为这就是我需要的。还感谢@SteveSchmitt为您提供的出色答案。我想知道您是否可以谈谈如何实现您在上一条评论末尾提到的“确保当前用户只保存允许保存的单个实体”。例如,如果帐户
有一个应用程序用户所有者
,该所有者是唯一允许编辑该帐户的用户。如果在Web API方法中使用[Authorize]属性,则该用户将可用。然后,您可以在上下文提供程序的构造函数中传递该用户,并基于该用户应用业务规则。
[HttpPost]
public SaveResult SaveAccount(JObject saveBundle)
{
var context = new AccountManagementContextProvider();
return context.SaveChanges(saveBundle);
}
[HttpPost]
public SaveResult SaveInventory(JObject saveBundle)
{
var context = new InventoryContextProvider();
return context.SaveChanges(saveBundle);
}
var saveOptions = new breeze.SaveOptions({ resourceName: 'SaveInventory' });
return manager.saveChanges(null, saveOptions);