public async Task<SaveResult> SaveChanges(IEnumerable<IEntity> entitiesToSave, SaveOptions saveOptions) {
   var entityManager = entitiesToSave.First().EntityAspect.EntityManager;
   var saveBundleNode = PrepareSaveBundle(entitiesToSave, saveOptions);
   try {
     var saveResultJson =
       await saveOptions.DataService.PostAsync(saveOptions.ResourceName, saveBundleNode.Serialize());
     var jn = JNode.DeserializeFrom(saveResultJson);
     if (jn.HasValues("Errors") || jn.HasValues("errors")) {
       throw new SaveException(entityManager, jn);
     }
     return ProcessSaveResult(entityManager, saveOptions, jn);
   } catch (DataServiceRequestException dsre) {
     var jn = JNode.DeserializeFrom(dsre.ResponseContent);
     throw new SaveException(entityManager, jn);
   } catch (HttpRequestException e) {
     throw new SaveException(e.Message, e);
   }
 }
示例#2
0
        private SaveResult ProcessSaveResult(EntityManager entityManager, SaveOptions saveOptions, string saveResultJson)
        {
            var jo = JObject.Parse(saveResultJson);

            var jn          = new JNode(jo);
            var kms         = jn.GetArray <KeyMapping>("KeyMappings");
            var keyMappings = kms.Select(km => ToEntityKeys(km)).ToDictionary(tpl => tpl.Item1, tpl => tpl.Item2);

            using (entityManager.NewIsLoadingBlock(false)) {
                keyMappings.ForEach(km => {
                    var targetEntity = entityManager.GetEntityByKey(km.Key);
                    targetEntity.EntityAspect.SetDpValue(km.Key.EntityType.KeyProperties[0], km.Value.Values[0]);
                });

                var prop = jo.Property("Entities");
                if (prop == null)
                {
                    return(null);
                }
                var entityNodes    = (JArray)prop.Value;
                var serializer     = new JsonSerializer();
                var mappingContext = new MappingContext()
                {
                    EntityManager      = entityManager,
                    MergeStrategy      = MergeStrategy.OverwriteChanges,
                    LoadingOperation   = LoadingOperation.Save,
                    JsonResultsAdapter = saveOptions.DataService.JsonResultsAdapter
                };
                var jsonConverter = new JsonEntityConverter(mappingContext);
                serializer.Converters.Add(jsonConverter);
                // Don't use the result of the Deserialize call to get the list of entities
                // because it won't include entities added on the server.
                serializer.Deserialize <IEnumerable <IEntity> >(entityNodes.CreateReader());
                var allEntities = mappingContext.Entities;
                allEntities.ForEach(e => e.EntityAspect.AcceptChanges());
                return(new SaveResult(allEntities, keyMappings));
            }
        }
 private JNode PrepareSaveBundle(IEnumerable<IEntity> entitiesToSave, SaveOptions saveOptions) {
   var jn = new JNode();
   jn.AddArray("entities", entitiesToSave.Select(e => EntityToJNode(e)));
   jn.AddJNode("saveOptions", saveOptions);
   return jn;
 }
    private SaveResult ProcessSaveResult(EntityManager entityManager, SaveOptions saveOptions, JNode jNode) {

      var kms = jNode.GetArray<KeyMapping>("KeyMappings");
      var keyMappings = kms.Select(km => ToEntityKeys(km, entityManager.MetadataStore)).ToDictionary(tpl => tpl.Item1, tpl => tpl.Item2);
      using (entityManager.NewIsLoadingBlock(false)) {
        keyMappings.ForEach(km => {
          var targetEntity = entityManager.GetEntityByKey(km.Key);
          targetEntity.EntityAspect.SetDpValue(km.Key.EntityType.KeyProperties[0], km.Value.Values[0]);
        });

        var entityNodes = jNode.GetToken<JArray>("Entities");

        var serializer = new JsonSerializer();
        var mappingContext = new MappingContext() {
          EntityManager = entityManager,
          MergeStrategy = MergeStrategy.OverwriteChanges,
          LoadingOperation = LoadingOperation.Save,
          JsonResultsAdapter = saveOptions.DataService.JsonResultsAdapter
        };
        var jsonConverter = new JsonEntityConverter(mappingContext);
        serializer.Converters.Add(jsonConverter);
        // serializer.Converters.Add(new StringEnumConverter());
        // Don't use the result of the Deserialize call to get the list of entities 
        // because it won't include entities added on the server.
        serializer.Deserialize<IEnumerable<IEntity>>(entityNodes.CreateReader());
        var allEntities = mappingContext.Entities;
        allEntities.ForEach(e => e.EntityAspect.AcceptChanges());
        return new SaveResult(allEntities, keyMappings);
      }

    }
示例#5
0
 public SaveOptions(SaveOptions saveOptions) {
   ResourceName = saveOptions.ResourceName;
   DataService = saveOptions.DataService;
   Tag = saveOptions.Tag;
 }
示例#6
0
        public async Task <SaveResult> SaveChanges(IEnumerable <IEntity> entitiesToSave, SaveOptions saveOptions)
        {
            var entityManager  = entitiesToSave.First().EntityAspect.EntityManager;
            var saveBundleNode = PrepareSaveBundle(entitiesToSave, saveOptions);

            try {
                var saveResultJson =
                    await saveOptions.DataService.PostAsync(saveOptions.ResourceName, saveBundleNode.Serialize());

                var jn = JNode.DeserializeFrom(saveResultJson);
                if (jn.HasValues("Errors") || jn.HasValues("errors"))
                {
                    throw new SaveException(entityManager, jn);
                }
                return(ProcessSaveResult(entityManager, saveOptions, jn));
            } catch (DataServiceRequestException dsre) {
                var jn = JNode.DeserializeFrom(dsre.ResponseContent);
                throw new SaveException(entityManager, jn);
            } catch (HttpRequestException e) {
                throw new SaveException(e.Message, e);
            }
        }
示例#7
0
 public SaveOptions(SaveOptions saveOptions)
 {
     ResourceName = saveOptions.ResourceName;
     DataService  = saveOptions.DataService;
     Tag          = saveOptions.Tag;
 }
示例#8
0
 public async Task SaveWithEntityErrorsException() {
   var em1 = await TestFns.NewEm(_serviceName);
   //        ok(true, "Skipped test - OData does not support server interception or alt resources");
   //        ok(true, "Skipped test - Mongo does not YET support server side validation");
   var twoCusts = CreateParentAndChildren(em1);
   var so = new SaveOptions("SaveWithEntityErrorsException", tag: "entityErrorsException");
   try {
     var sr0 = await em1.SaveChanges(so);
     Assert.Fail("should not get here");
   } catch (SaveException e) {
     Assert.IsTrue(e.EntityErrors.Count == 2, "should have two errors");
     var order1 = twoCusts.Cust1.Orders[0];
     Assert.IsTrue(order1.EntityAspect.ValidationErrors.Count == 1);
     var order2 = twoCusts.Cust1.Orders[1];
     Assert.IsTrue(order2.EntityAspect.ValidationErrors.Count == 1);
     Assert.IsTrue(order2.EntityAspect.ValidationErrors.First().Context.PropertyPath == "OrderID");
   } catch (Exception e) {
     Assert.Fail("should not get here - wrong exception" + e.Message);
   }
   // now save it properly
   var sr1 = await em1.SaveChanges();
   Assert.IsTrue(sr1.Entities.Count == 4);
 }
示例#9
0
 public async Task SaveWithServerExit() {
   var em1 = await TestFns.NewEm(_serviceName);
   //  ok(true, "Skipped test - OData does not support server interception or alt resources");
   CreateParentAndChildren(em1);
   var so = new SaveOptions("SaveWithExit", tag: "exit");
   var sr0 = await em1.SaveChanges(so);
   Assert.IsTrue(sr0.Entities.Count == 0);
 }
示例#10
0
    public async Task CaptureAddlSavesDoneOnServer() {
      var em1 = await TestFns.NewEm(_serviceName);

      //        ok(true, "Skipped test - OData does not support server interception or alt resources");
      //        ok(true, "N/A for Mongo - test not yet implemented - requires server side async call");
      var q = new EntityQuery<Category>().Where(c => c.CategoryName.StartsWith("Beverage")).Expand("Products");
      var r = await q.Execute(em1);
      var category = r.First();
      var products = category.Products;
      var prices = products.Select(p => p.UnitPrice).ToList();
      category.CategoryName = TestFns.MorphString(category.CategoryName);
      var so = new SaveOptions(tag: "increaseProductPrice");
      var sr = await em1.SaveChanges(null, so);
      Assert.IsTrue(sr.Entities.Count == 13, "should have saved 13 entities + 1 category + 12 products");
      Assert.IsTrue(sr.Entities.OfType<Product>().Count() == 12, "should be 12 products");
      var ek = category.EntityAspect.EntityKey;
      var em2 = new EntityManager(em1);
      var r2 = await em2.ExecuteQuery(ek.ToQuery<Category>().Expand("Products"));
      var cat2 = r2.First();
      var products2 = cat2.Products;

      var newPrices = products2.Select(p => p.UnitPrice).ToList();
      Assert.IsTrue(!prices.SequenceEqual(newPrices), "prices should have changed");
    }
示例#11
0
    public async Task ExceptionThrownOnServer() {
      var em1 = await TestFns.NewEm(_serviceName);

      //  ok(true, "Skipped test - OData does not support server interception or alt resources");

      var q = new EntityQuery<Order>().Take(1);
      var orders = await em1.ExecuteQuery(q);
      var order = orders.First();
      order.Freight = order.Freight + .5m;
      var so = new SaveOptions("SaveAndThrow", tag: "SaveAndThrow");
      try {
        var sr = await em1.SaveChanges(null, so);
        Assert.Fail("should not get here");
      } catch (SaveException se) {
        Assert.IsTrue(se.Message.Contains("Deliberately thrown"), "message should be correct");
      }
    }