冒泡Update Concurrency Exceptions查看

Bubbling up Update Concurrency Exceptions to view

将 DbUpdateConcurrencyException 冒泡到 grain 视图的好方法是什么?

我目前正在研究 Orlean 的原型,它具有我正在使用的自定义状态 Entity Framework Core 与数据库通信并使用 EF Core 中内置的乐观并发模式来管理并发问题.

我遇到的问题是我想将我的异常从颗粒中冒泡到视图中,但在视图端没有收到它。

我正在尝试完成此操作,因为我想处理一些对视图更紧迫的并发问题,以便用户可以决定或至少收到有关该问题的警报。

我在 Orlean's Gitter 上提出了这个问题,但没有从中得到很多想法。

我的更新代码示例:

 public Task UpdateUser(User user)
    {
        //Reason for second try/catch is to bubble the error to controller
        try
        {
            userState = new User
            {
                Username = this.GetPrimaryKeyString(),
                accountType = user.accountType,
                FName = user.FName,
                LName = user.LName,
                RowVersion = user.RowVersion,
                CreatedDate = user.CreatedDate
            };
            UpdateState();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            throw ex;
        }
        return Task.CompletedTask;
    }


 public Task UpdateState()
    {
        using (var context = new OrleansContext())
        {
            context.users.Update(userState);
            try
            {
                context.SaveChanges();
            }
            catch ( DbUpdateConcurrencyException ex)
            {
                var entry = ex.Entries.Single();
                var clientValues = (User)entry.Entity;
                var databaseEntry = entry.GetDatabaseValues();
                //Make sure the row wasn't deleted
                if(databaseEntry != null)
                {
                    var databaseValues = (User)databaseEntry.ToObject();
                    if(clientValues.accountType != databaseValues.accountType)
                    {
                        //Bubble up the exception to controller for proper handling
                        throw ex;
                    }
                    //Update Row Version to allow update
                    userState.RowVersion = databaseValues.RowVersion;
                    context.SaveChanges();
                }                
            }
        }
        return Task.CompletedTask;
    }

我愿意接受关于此的任何建议,只要它允许用户收到异常警报并可以查看他们的数据和当前数据库值。

异常有可能没有被正确序列化或反序列化。主要原因可能是:

  1. 异常 class 没有正确实现 ISerializable 模式。
  2. 客户端不存在包含异常class的程序集,因此客户端不理解如何创建异常类型。

在这种情况下,我会倾向于第二个原因,因为 大多数 (但不是全部!)例外 classes 确实正确地实现了 ISerializable 模式。

在任何一种情况下,您都可以捕获您的异常并将其转换为一般异常。 您可以使用 Orleans 的 LogFormatter.PrintException(Exception) 方法创建一个辅助方法来将异常格式化为字符串。

public static void ThrowPlainException(Exception e) =>
    throw new Exception(Orleans.Runtime.LogFormatter.PrintException(e));

我想到的解决方案是创建一个自定义异常 class,可序列化将数据库值对象添加到其中并将其冒泡到视图中。

[Serializable]
public class UpdateException : Exception
{
    public object databaseValues { get; set; }
    public UpdateException(object databaseValues)
    {
        this.databaseValues = databaseValues;
    }
    public UpdateException(string message, object databaseValues) :base(message)
    {
        this.databaseValues = databaseValues;
    }
}