BreezeJS 在 .NET 中重构服务器上的 SaveResult
BreezeJS Reconstruct SaveResult on Server in .NET
我没有使用 Breeze 服务器端来保存 JObject,而是使用虚拟上下文提供程序来提取 EntityMap,然后对每个实体执行自定义验证并自己保存它们。如果保存成功,我如何将 SaveResult 对象重构为 return 返回给客户端,以便 BreezeJS 客户端知道我的更改?
目前我正在return生成以下 SaveResult:
// Using example here (https://github.com/Breeze/breeze.js.samples/issues/33)
// to extract EntityMaps from JObject.
// The return result is a Dictionary<Type, EntityInfo>.
var entityMaps = SaveBundleToSaveMap.Convert(saveBundle);
// ... Code to save entities to DB
// SaveResult to be returned to the client.
return new SaveResult()
{
Entities = entityMaps.SelectMany(innerEi => innerEi.Value.Select(ie => ie.Entity)).ToList<object>(),
Errors = null,
KeyMappings = new List<KeyMapping>()
};
如何为单个主键构建 KeyMapping 列表?如何为复合键构造 KeyMapping?
经过反复试验,我发现 SaveResult.KeyMapping
列表仅包含从插入的实体生成的新旧密钥。这是有道理的,因为客户端有更新的密钥,不需要担心删除的实体。
构建SaveResult.KeyMapping
列表,首先需要将每个插入实体的EntityInfo.AutoGeneratedKey.TempValue
设置为客户端发送过来的key,保存实体得到新的key,然后创建KeyMapping
列出并 return 返回给客户端。
1.Loop entityMaps
并将每个 EntityInfo
的 TempValue
设置为从客户端发送的 key/id。
// Extract out from loop to make it more readable.
Action<EntityInfo> processEntityInfo = (ei) =>
{
if (ei.EntityState == EntityState.Added && (ei.AutoGeneratedKey != null && ei.AutoGeneratedKey.AutoGeneratedKeyType == AutoGeneratedKeyType.Identity))
{
var entity = ei.Entity;
var tempValue = ei.AutoGeneratedKey.Property.GetValue(entity);
ei.AutoGeneratedKey.TempValue = tempValue;
}
};
entityMaps.ToList().ForEach(map => map.Value.ForEach(ei => processEntityInfo(ei)));
2.Save 通过在 EntityFramework 上下文中调用 Context.SaveChanges()
实体。这将为所有插入的实体生成密钥。
3.Loop 通过实体映射中保存的实体并构建 return KeyMapping
列表。
return entityMaps.SelectMany(entityMap =>
entityMap.Value
.Where(entityInfo => entityInfo.EntityState == EntityState.Added && (entityInfo.AutoGeneratedKey != null && entityInfo.AutoGeneratedKey.AutoGeneratedKeyType == AutoGeneratedKeyType.Identity))
.Select(entityInfo => new KeyMapping
{
EntityTypeName = entityInfo.Entity.GetType().FullName,
RealValue = entityInfo.AutoGeneratedKey.Property.GetValue(entityInfo.Entity),
TempValue = entityInfo.AutoGeneratedKey.TempValue
}));
我没有使用 Breeze 服务器端来保存 JObject,而是使用虚拟上下文提供程序来提取 EntityMap,然后对每个实体执行自定义验证并自己保存它们。如果保存成功,我如何将 SaveResult 对象重构为 return 返回给客户端,以便 BreezeJS 客户端知道我的更改?
目前我正在return生成以下 SaveResult:
// Using example here (https://github.com/Breeze/breeze.js.samples/issues/33)
// to extract EntityMaps from JObject.
// The return result is a Dictionary<Type, EntityInfo>.
var entityMaps = SaveBundleToSaveMap.Convert(saveBundle);
// ... Code to save entities to DB
// SaveResult to be returned to the client.
return new SaveResult()
{
Entities = entityMaps.SelectMany(innerEi => innerEi.Value.Select(ie => ie.Entity)).ToList<object>(),
Errors = null,
KeyMappings = new List<KeyMapping>()
};
如何为单个主键构建 KeyMapping 列表?如何为复合键构造 KeyMapping?
经过反复试验,我发现 SaveResult.KeyMapping
列表仅包含从插入的实体生成的新旧密钥。这是有道理的,因为客户端有更新的密钥,不需要担心删除的实体。
构建SaveResult.KeyMapping
列表,首先需要将每个插入实体的EntityInfo.AutoGeneratedKey.TempValue
设置为客户端发送过来的key,保存实体得到新的key,然后创建KeyMapping
列出并 return 返回给客户端。
1.Loop entityMaps
并将每个 EntityInfo
的 TempValue
设置为从客户端发送的 key/id。
// Extract out from loop to make it more readable.
Action<EntityInfo> processEntityInfo = (ei) =>
{
if (ei.EntityState == EntityState.Added && (ei.AutoGeneratedKey != null && ei.AutoGeneratedKey.AutoGeneratedKeyType == AutoGeneratedKeyType.Identity))
{
var entity = ei.Entity;
var tempValue = ei.AutoGeneratedKey.Property.GetValue(entity);
ei.AutoGeneratedKey.TempValue = tempValue;
}
};
entityMaps.ToList().ForEach(map => map.Value.ForEach(ei => processEntityInfo(ei)));
2.Save 通过在 EntityFramework 上下文中调用 Context.SaveChanges()
实体。这将为所有插入的实体生成密钥。
3.Loop 通过实体映射中保存的实体并构建 return KeyMapping
列表。
return entityMaps.SelectMany(entityMap =>
entityMap.Value
.Where(entityInfo => entityInfo.EntityState == EntityState.Added && (entityInfo.AutoGeneratedKey != null && entityInfo.AutoGeneratedKey.AutoGeneratedKeyType == AutoGeneratedKeyType.Identity))
.Select(entityInfo => new KeyMapping
{
EntityTypeName = entityInfo.Entity.GetType().FullName,
RealValue = entityInfo.AutoGeneratedKey.Property.GetValue(entityInfo.Entity),
TempValue = entityInfo.AutoGeneratedKey.TempValue
}));