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 并将每个 EntityInfoTempValue 设置为从客户端发送的 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
    }));