【问题标题】:Breezejs SaveChanges: is it possible to return a custom SaveResult object, somehow?Breezejs SaveChanges:是否有可能以某种方式返回自定义 SaveResult 对象?
【发布时间】:2014-04-30 03:16:40
【问题描述】:

假设我有一个平均分数的电影实体。用户可以对电影进行评分,为此我在客户端调用 datacontext.savechanges,将 Rating 对象发送到服务器。在服务器端,调用 SaveChanges 方法,在 BeforeSaveEntity 方法中,我调整了电影的平均分。

问题来了:如何从服务器的 SaveChanges 方法(例如在 SaveResult 对象中)返回平均分数?

我以为我可以将电影实体添加到 SaveResult 实体列表中,但随后: - 我需要从 saveBundle 参数中访问属性 - 我必须重新查询数据库,这是我在 BeforeSaveEntity 中所做的

谢谢

尼古拉斯

【问题讨论】:

  • 更新 BeforeSaveEntities 方法中的分数。请务必将持有 score 属性的实体包含到保存地图中。
  • 是的,我应该可以这样做,但会出现“序列不包含匹配元素”错误。
  • 一些代码可以帮助我更好地理解这个问题。不要忘记您可以覆盖 SaveChangesCore,这可能会提供一些调整内容的机会。然后,在 Web API 返回 SaveResult 之前,您还有另一个机会(您可以在某个地方存储一个值以在控制器中使用)。最后,SaveResult 本身并没有什么神圣之处。从客户端的角度来看,它是一种结构类型:任何序列化预期内容的内容都将被 BreezeJS EntityManager 接受。很多选择。
  • 有趣!但是,您提到的方法(SaveChangesCore)在文档中找不到。 (breezejs.com/documentation/custom-efcontextprovider) 仅在 NoDB 示例中提到,此后我没有阅读过。我使用 DB :)。无论如何,与此同时,我实际上使用了一种解决方法并将我需要的值存储在 System.Web.HttpContext.Current.Items 中。

标签: breeze


【解决方案1】:

正如 pawel 在 cmets 中指出的那样:要在 SaveChanges 承诺中返回电影,请在自定义 EFContextProvider 上的 BeforeSaveEntities 方法中更新电影并将其添加到 saveMap。

我已经为你整理了一些代码。

protected override Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type,   List<EntityInfo>> saveMap) {
    Movie movie = null;
    // initialize the movie variable and update the movie as needed
    saveMap.Add(typeof(Movie), movie);

    return saveMap;
  }

【讨论】:

  • 我对 BeforeSaveEntities 选项的问题是:我有 2 个 DbContext,一个向世界公开,即“DTO”上下文。这是创建元数据的地方。该上下文的任何类实际上都没有保存在数据库中。一切都被转换并映射到“私人”上下文中。我的理解是,我无法将“私有”上下文中的类实例添加到保存映射,因为这会产生“序列不包含匹配元素”错误。我不能在那里添加 DTO,因为这些对象没有实际的数据库。
  • 我不清楚为什么 DTO 上下文中没有 Movie.Score?您不必将分数保存到数据库 - 将其设为只读。
  • “使其成为只读”是什么意思?我所知道的是我无法将 MovieDTO 添加到 saveMap,因为它无法保存在数据库中,并且我无法将 Movie 添加到保存地图,因为它会产生我提到的错误。但是我找到了一种方法可以将我想要的实体添加到 saveResult 中,所以没关系。
【解决方案2】:

是的,有可能。

像往常一样针对 EDMX 编写控制器。对我们来说,它翻译成这样的:

public class PersonalizationController : MultiTenantBreezeController<PersonalizationEntities>

其中 PersonalizationEntities 是 ObjectContext。

然后在服务器上,我们简单地定义 SaveChanges(不要介意覆盖,我们确实有一个基类)

[HttpPost]
public override SaveResult SaveChanges(JObject saveBundle)
{
     // Deserialize the object that needs to get saved (ApplicationDefaults is my DTO)
     var applicationDefaultsList = JsonConvert.DeserializeObject<List<ApplicationDefaults>>(saveBundle.SelectToken("entities").ToString());

     // Do whatever logic you need to save the data
     using (var repo = ServiceLocator.Current.Container.Resolve<IUserPreferenceRepository>())
     {
          // Your save logic here
     }

     // Construct the save result to inform the client that the server has completed the save operation
     var keyMappings = new List<KeyMapping>();
     return new SaveResult()
     {
         Entities = applicationDefaultsList.Cast<object>().ToList(),
         Errors = null,
         KeyMappings = keyMappings
     };
}

【讨论】:

    猜你喜欢
    • 2015-12-07
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 2014-09-24
    • 1970-01-01
    • 2016-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多