【发布时间】:2016-09-12 19:50:44
【问题描述】:
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 表中必须有一个时间戳列,但这并不能解决我的问题,因为在我的 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业务层。这是真的?如果这是真的,我想这不是一个好的解决方案。但是,我该如何控制并发呢?
谢谢。
【问题讨论】:
标签: entity-framework architecture data-access-layer business-logic-layer