如何在具有并发控制的 .NET 和 EF 应用程序中设计持久层?
How to design the persistence layer in a .NET and EF application with concurrency control?
I have read this post 我认为这个理论很清楚。我有一个 DAL,它只有在数据库中添加、获取、更新和删除信息的方法。
所以我想我有一个应用程序,其中有客户、订单和客户类型。客户类型有一个百分比,用于设置对一种客户类型的折扣。
- 业务层向 DAL 请求客户端类型以了解折扣。
- 业务层创建带有价格的订单并根据客户类型应用折扣。
- 业务层向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..
I have read this post 我认为这个理论很清楚。我有一个 DAL,它只有在数据库中添加、获取、更新和删除信息的方法。
所以我想我有一个应用程序,其中有客户、订单和客户类型。客户类型有一个百分比,用于设置对一种客户类型的折扣。
- 业务层向 DAL 请求客户端类型以了解折扣。
- 业务层创建带有价格的订单并根据客户类型应用折扣。
- 业务层向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..