gpt4 book ai didi

c# - 如何将Breeze与通用工作单元和存储库一起使用?

转载 作者:行者123 更新时间:2023-11-30 13:37:48 24 4
gpt4 key购买 nike

使用这个:

https://genericunitofworkandrepositories.codeplex.com/

以及以下博客文章集:

http://blog.longle.net/2013/05/11/genericizing-the-unit-of-work-pattern-repository-pattern-with-entity-framework-in-mvc/

我们正在尝试将这些存储库与Breeze一起使用,因为它可以很好地处理客户端javascript和OData。

我想知道我们如何在Breeze中使用它们来正确地覆盖BeforeSaveEntity

在保存期间,我们有很多业务逻辑需要进行(修改诸如ModifiedByModifiedTimeCreatedBy之类的属性),但是当我们更改这些逻辑时,它们不会被轻而易举地更新,因此我们必须保存后重新查询(我们尝试手动将更改映射回去,但这需要我们重复所有业务逻辑)。

我们的第二个选择是检查每个entity的类型,然后为其请求正确的存储库,在内部处理保存,然后在客户端上执行新的get请求以获取更新的信息。虽然这很有趣,所以我们希望有更好的方法。在绕过微风的保存而又不返回错误或不必随后获取数据的情况下更新这些对象的正确方法是什么?

保存过程中带有Business Logic的Breeze的任何示例都将非常有帮助,特别是如果它发生在服务,存储库或直接在BeforeSaveEntity方法中的其他事件中。

最佳答案

这是许多问题汇总成一个问题,每个问题都是一个大话题。我能做的最好的就是将您指向某些方向。

在开始介绍之前,让我解释一下为什么您看不到设置“ ModifiedByModifiedTimeCreatedBy等属性)的效果​​。 EFContextProvider不会更新已修改实体的每个属性,而是仅更新EntityInfo.OriginalValuesMap中提到的那些属性,即属性名称和仅已更改属性的原始值的词典。如果要保存仅在服务器上设置的属性,只需将其添加到原始值映射即可:

var map = EntityInfo.OriginalValuesMap;
map["ModifiedBy"]=null; // the original value does not matter
map["ModifiedTime"]=null;


现在,Breeze知道也要保存这些属性,它们的新值将返回给客户端。

让我们回到大局。

Breeze首先是客户端JavaScript库。只要您的服务器使用HTTP和JSON,您就可以在服务器端执行几乎任何您想做的事情,并使Breeze对此感到满意。

无论您喜欢哪种技术,编写提供所需功能的服务器都不是一件容易的事。 Breeze的作者提供了一些现成的.NET组件,使您的工作更加轻松,尤其是当您选择Web API,EF和SQL Server堆栈时。

我们的.NET演示通常将所有内容都放入一个Web应用程序中。那不是我们练习的方式。在现实生活中,我们永远不会在Web API控制器中实例化Breeze EFContextProvider。该控制器(或多个控制器)将委派给负责业务逻辑和数据访问的外部类,也许是存储库或工作单元(UoW)类。

带Breeze .NET组件的存储库模式

我们倾向于为模型(通常是POCO),数据访问(ORM)和Web(Web API加客户端资产)项目创建单独的项目。您将在 DocCode Sample中以及约翰·帕帕(John Papa)的Code Camper示例中看到这种分隔,他的PluralsSight课程“ Building Apps with Angular and Breeze”的同伴。

这些样本还演示了存储库模式的实现,该模式将多个存储库和UoW的职责混合在一类中。对于这些样本中的小型模型,这是有意义的。没有什么可以阻止您将存储库重构为单独的类。

我们将存储库类与EF数据访问材料保留在同一项目中,因为我们认为为此目的创建另一个项目没有特殊价值。如果您决定重构一个单独的项目,这并不困难。

Breeze和Code Camper样本均专注于Breeze客户开发。它们在服务器端逻辑上比较薄。也就是说,您将在DocCode示例的“ NorthwindRepository.cs”和“ NorthwindEntitySaveGuard.cs”文件的 BeforeSaveEntities扩展点中找到应用自定义业务逻辑的有价值的线索。以及基于发出请求的用户的那些类型的某些记录。

如果您尝试通过单个端点引导所有保存更改请求,则逻辑可能会令人不知所措。您不必这样做。您可能有几个保存端点,每个保存端点专用于特定的业务操作,这些端点仅限于以高度特定的方式插入/更新/删除几种类型的实体。您可以随心所欲。请参见 "Saving Entities" topic中的“命名保存”。

随你便

现在有无数种方法来实现存储库和UoW模式。

您可以按照您引用的帖子中列出的方式进行操作。在这种情况下,您不需要Breeze .NET组件。将您的Web API查询方法(是否为 IQueryable)连接到返回 IQueryable(或只是对象)的存储库方法是很简单的。 Web API不必知道您是否在后台有Breeze EFContextProvider或完全不同的东西。

处理Breeze客户端的 SaveChanges请求有点棘手。也许您可以从 ContextProviderEFContextProvider派生;也许不吧。 Study the "ContextProvider.cs" documentationsource code,尤其是 SaveChanges方法,您将看到需要做些什么来使Breeze客户端满意并与之交互,但是您想使用UoW处理变更集保存。

假设您没有在客户端进行任何更改(这是一个假设,而不是给定的...如果需要,您可以更改保存协议),您的 SaveChanges只需要做两件事:


从客户端解释“ saveBundle”。
返回结构类似于 SaveResult的内容


saveBundle是一个JSON包,您可能不想解压缩自己。幸运的是,您可以从 ContextProvider派生一个类,该类仅用于将 saveBundle转换为“ SaveMap”,即 EntityInfo对象的字典,几乎是任何人在分析变更集时都想使用的对象用于验证和保存。

以下可能会解决问题:

using System;
using System.Collections.Generic;
using System.Data;
using Breeze.ContextProvider;
using Newtonsoft.Json.Linq;

public class SaveBundleToSaveMap : ContextProvider
{
// Never create a public instance
private SaveBundleToSaveMap(){}

/// <summary>
/// Convert a saveBundle into a SaveMap
/// </summary>
public static Dictionary<Type, List<EntityInfo>> Convert(JObject saveBundle)
{
var dynSaveBundle = (dynamic) saveBundle;
var entitiesArray = (JArray) dynSaveBundle.entities;
var provider = new SaveBundleToSaveMap();
var saveWorkState = new SaveWorkState(provider, entitiesArray);
return saveWorkState.SaveMap;
}

// override abstract members but DO NOT USE ANY OF THEM

}


然后由您决定如何使用“ SaveMap”并调度到您的业务逻辑。

SaveResult是一个简单的结构:

public class SaveResult {
public List<Object> Entities; // each of the entity type you serialize to the client
public List<KeyMapping> KeyMappings;
public List<Object> Errors;
}

public class KeyMapping {
public String EntityTypeName;
public Object TempValue;
public Object RealValue;
}


照原样使用这些类或构建自己的类。 Breeze客户端关心的是JSON,而不是这些类型。

关于c# - 如何将Breeze与通用工作单元和存储库一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20714180/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com