如何在具有并发控制的 .NET 和 EF 应用程序中设计持久层?

How to design the persistence layer in a .NET and EF application with concurrency control?

I have read this post 我认为这个理论很清楚。我有一个 DAL,它只有在数据库中添加、获取、更新和删除信息的方法。

所以我想我有一个应用程序,其中有客户、订单和客户类型。客户类型有一个百分比,用于设置对一种客户类型的折扣。

在代码中我可以这样:

达尔:

public async getClientType(long paramIDClientType)
{
    using(Entities myDbContext = new Entities())
    {
        return await myDbContext.ClientTypes.Where(x=> x.IDType == paramIDClientType).SingleOrDefault();
    }
}

public async addOrder(Orders paramNewOrder)
{
    using(Entities myDbContext = new Entities())
    {
        myDbContext.Orders.Local.Add(paramNewOrder);
        await myDbContext.SaveChangesAsync();
    }
}

业务层:

public void addOrderToClient(CLients paramClient)
{
    ClientTypes myType = myDAL.getClientType(paramClient.IDClient);

    ORder myNewOrder = myNewOder();
    myNewOrder.IDClient = paramClientIdCLient;
    myNewOder.Amount = 300;
    myNewOrder.Discount = myType.Discount;
    myNewOder.Total = nyNewOrder.Total - myNewOder.Amount * myNewOder.Discount;

    myDAL.AddOrder(nyNewOrder);
}

但是我在这种情况下的并发性有问题,因为我想确保我使用正确的折扣,所以我想避免一种类型的客户的折扣被另一个用户更改。添加新订单的过程。

如果我使用开放式并发,我的 ClientTypes 中必须有一个时间戳列 table,但这并没有解决我的问题,因为在我的 DAL 层的 addOrder 方法中,我只将新订单,所以该方法没有时间戳值,业务层会检查客户端类型是否已更改,以确保使用的折扣是正确的。

所以我在考虑这个解决方案:

public async addOrder(Orders paramNewOrder)
{
    using(Entities myDbContext = new Entities())
    {
        string sql = "select ct.* from ClientTypes as ct, CLients as c"
            + " where ct.IdType = c.IdType and c.IdType = " + paramNewOrder.IdCLient;

        ClientTypes myClientType = await myDbContext.CLientTypeSqlQuery<CLientTypes>(sql).SingleOrDefaultAsync();

        if(paramNewOrder.Discount != myCLientType)
        {
            throw new Exception("Discount incorrect.");
        }

        paramNewOrder.Total = paramNewOrder.Amount - paramNewOrder.Amount * myClientType.Discount;

        myDbContext.Orders.Local.Add(paramNewOrder);
        await myDbContext.SaveChangesAsync();
    }
}

这是我的业务层,但是使用EF来获取数据,所以我认为这个解决方案合并了DAL abd业务层。这是真的?如果这是真的,我想这不是一个好的解决方案。但是,我该如何控制并发?

谢谢。

是的,乐观并发控制无法帮助您防止插入错误的新订单,因为您没有提交 ClientType。如果同时更改折扣,则仅更新 ClientType 会引发异常。

但仔细考虑要求。修改后毫秒使用正确的折扣真的很重要吗?如果是这样,您必须寻找锁定机制。否则,只在最后一刻获取当前折扣,进行计算并提交订单。

您可以在映射到 Order 的插入操作的存储过程中实现 locking/calculation/insert 机制。 EF can map CUD actions to stored procedures..