0

I have read this post и теория, я думаю, это ясно. У меня есть DAL, который имеет только методы для добавления, получения, обновления и удаления информации в базе данных.Как создать слой persistence в приложении .NET и EF с контролем параллелизма?

Так что я предполагаю, что у меня есть приложение, в котором у меня есть клиенты, заказы и тип клиента. Тип клиента имеет процент, который устанавливает скидку для клиента.

  • Просьба к бизнес-слою запрашивать у 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(); 
    } 
} 

Bussiness слой:

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); 
} 

Но у меня есть проблема с параллелизмом в этом случае, потому что я хочу, чтобы я использовал правильную скидку, поэтому я хочу, чтобы скидка на тип клиента была изменена другим пользователем в середине процесса добавления новый порядок.

Если я использую оптимистический параллелизм, у меня должен быть столбец timestamp в моей таблице ClientTypes, но это не решает мою проблему, потому что в методе addOrder в моем слое DAL я передаю только как новый новый порядок, поэтому метод dom't имеет значение timestamp, которое имеет уровень бизнес-уровня, чтобы проверить, изменился ли тип клиента, чтобы убедиться, что используемая скидка является правильной.

ПОЭТОМУ Я имею в виду, в этом решении:

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.CLientTypeSqlQuiery<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(); 
    } 
} 

Это мой Bussiness слой, но и использовать EF, чтобы получить данные, так что я думаю, что это решение объединить DAL абд BUSSINESS слой. Это правда? Если это так, я думаю, это нехорошее решение. Но тогда, как я мог контролировать параллелизм?

Спасибо.

ответ

1

Да, оптимистичный контроль параллелизма не помогает предотвратить вставку неисправного нового заказа, поскольку вы не фиксируете ClientType. Только обновление ClientType приведет к возникновению исключения, если скидка была изменена в среднем.

Но внимательно рассмотрите требования. Действительно ли первостепенное значение имеет правильная скидка миллисекунды после ее изменения? Если это так, вам нужно искать механизм блокировки. В противном случае просто выберите текущую скидку в самый последний момент, выполните расчет и выполните заказ.

Вы можете реализовать механизм блокировки/вычисления/вставки в хранимой процедуре, которая сопоставляется с действием вставки Order. EF can map CUD actions to stored procedures..

+0

На самом деле это простой пример, возможно, очень простой. Но представьте, что один пользователь обновляет заказ от открытого до платного, и я хочу, чтобы второй пользователь не добавил новый элемент в заказ.Было бы возможно иметь платный заказ с товаром с ценой, которая не выплачивается. Надеюсь, этот пример более ясен. –

+1

Это не более ясно (вы уже были очень ясны), но это лучше :) Возможно, в этом случае вы также должны обновить заказ, если вы добавите в него элемент, поэтому оптимистичный параллелизм произойдет, если заказ будет изменен. В противном случае, здесь, вам нужна некоторая форма блокировки. –

+0

Но это «поддельное» обновление в заказе, потому что не нужно, поэтому это вариант, но мне все еще интересно, лучше ли это поддельное обновление или пезимический параллелизм. –