我的应用程序使用了BreezeJS, ASP。. NET Web API和EF.
我正在尝试使用breeze保存一个对象,如下所示:
var saveOptions = this.manager.saveOptions.using({ resourceName: "SaveLocationSettings", tag: clientId, allowConcurrentSaves: true });
var obj = self.manager.saveChanges(null, saveOptions).then(saveSucceeded, saveFailed);
我在服务器端使用一个自定义保存方法,它返回一个SaveResult对象。但是,在客户端,实体管理器仍然维护修改后的状态。
我在Web API上的控制器是一个BreezeController。
根据breeze文档,如果您的自定义方法具有与breeze SaveChanges()方法相似的签名,它应该与SaveChanges()方法相似。但是,如果我使用简单的SaveChanges(),则实体状态将得到正确更新。但是我的自定义端点保存不更新实体状态,尽管数据保存在数据库中。
更新:
经过一番调查,我发现这种情况只会发生在一个实体类型上,该实体类型会到达这个特定的保存端点。假设,我有一个'location'对象,与'availability'集合相关联,如下所示:
Class Location {
public Location() {
this.Availabilities = new HashSet<Availability>();
}
}
现在从客户端来看,如果我只更改Location对象的一些属性,它会正确地处理hasChanges属性。但是,如果我仅更改可用性或可用性以及位置的另一个属性,则在客户端无法正确更新hasChanges。
这是我从WebAPI控制器调用的服务器端代码:
public SaveResult SaveLocation(Location l, List<MaxAvailability> maxAvailability, int changedBy)
{
// Create a SaveResult object
// we need to return a SaveResult object for breeze
var keyMappings = new List<KeyMapping>();
var entities = new List<object> {l, maxAvailability};
var saveResult = new SaveResult() { Entities = entities, KeyMappings = keyMappings, Errors = null };
try
{
if (l.LocationId == -1)
{
// add new location
l.LocationId = this.AddNewLocationWithItsAssociatedData(l, maxAvailability, changedBy);
}
else
{
// do changes to the existing location
this.UpdateExistingLocationWithItsAssociatedData(l, maxAvailability, changedBy);
}
}
catch (DbEntityValidationException ex)
{
// Log the error and add the errors list to SaveResult.
// Retrieve the error messages as a list of strings.
saveResult.Errors = this.GetErrors(ex);
}
return saveResult;
}
我想我找到答案了。这是由于我的代码中一些不好的做法。在修改现有位置的可用性时,不是更新现有记录,而是删除现有记录并添加新记录。这导致客户端可用性对象和数据库对象具有两种不同的状态。一旦解决了这个问题,hasChanges()状态就会像预期的那样运行。