C# EF + Repository + UnitOfWorkk pattern
本文关键字:pattern UnitOfWorkk Repository EF | 更新日期: 2023-09-27 18:02:38
我有一个关于架构的问题,这是我的场景,我正在使用EF构建一个分层的解决方案,所以我为我的实体做了repository, UnitOfWork管理我的repository是完美的,我放了控制方法和事务工作,我的业务实体消耗了工作单元,我开始使用我的业务规则,但是我有一个问题,例如,有一种方法,我需要使用两种业务方法来避免代码重复,并在同一事务中工作,我怎么能做到这一点?
以下业务方法:
public void LinkCard(int cardId, long pin)
{
if (cardId < 1 || pin < 1)
throw new ArgumentException("Invalid parameters!");
using (UnitOfWorkBol uowb = new UnitOfWorkBol(Log))
{
try
{
Card card;
bool success = true;
Pin pinResult;
if(!Validator.UseRelesead(cardId, out card, uowb))
throw new CardException("La tarjeta no liberado para su uso!");
pinResult = uowb.RepositoryPin.LoadPinByPin(pin);
if(!Validator.UseRelesead(pinResult))
throw new CardException("La cuenta no está aprobado para su uso!");
//se não existir cadastra o novo cartão caso contrário só vincula
if (card == null)
{
card = new Card
{
CARD_ID = cardId,
DISABLED = false,
pin = pinResult
};
success = uowb.GetBaseRepository<Card>().Add(card);
}
else
{
card.pin = pinResult;
success = uowb.RepositoryCard.Update(card);
}
if (success)
uowb.SaveChanges();
}
catch (Exception ex)
{
Log.MostraMensagem(LogClass.MsgType.Error, 0, "LinkCard()" + ": " + ex.Message);
throw;
}
}
}
public void CancelCard(int cardId, int reasonId, long Epin)
{
if (cardId < 1)
throw new ArgumentException("Invalid parameter", "cardId");
using(UnitOfWorkBol uowb = new UnitOfWorkBol(Log))
{
try
{
if (Validator.IsCancelled(cardId, uowb))
throw new CardException("La tarjeta ya se cancela!");
Card card = uowb.GetBaseRepository<Card>().LoadById<int>(cardId);
if (card == null)
throw new CardException("Tarjeta no encontrada!");
//adiciona o cartão na tabela de cancelamento e o desativa
CancelCard cancel = new CancelCard()
{
card = card,
cashier_hist = uowb.RepositoryCashierHist.LoadCurrentCashierHist(Epin),
DATE = DateTime.Now,
reason_of_cancel = uowb.GetBaseRepository<ReasonOfCancel>().LoadById<int>(reasonId)
};
card.DISABLED = true;
card.pin = null;
bool success = uowb.GetBaseRepository<CancelCard>().Add(cancel);
if (success)
success = uowb.GetBaseRepository<Card>().Update(card);
if (success)
uowb.SaveChanges();
}
catch (Exception ex)
{
Log.MostraMensagem(LogClass.MsgType.Error, 0, "CancelCard()" + ": " + ex.Message);
throw;
}
}
}
我需要在一个事务上调用这些方法,谢谢!
伙计们,我使用了transactionScope,工作得很好,但我不喜欢这个解决方案,因为我正在打开许多交易下面的代码:
public void CancelAndLinkCard(CancelAndTransferDTO dto)
{
using (TransactionScope scope = new TransactionScope())
{
CancelCard(dto.OldCardId, dto.ReasonId, dto.Epin);
LinkCard(dto.NewCardId, dto.Pin);
scope.Complete();
}
}
可能使用外观模式和视图访问外观,这来控制事务更好,但我不知道我需要帮助,感谢回复
如果在两个方法中都要处理上下文,我真的不知道有什么办法可以做到。我可能会写另一个同时做这两件事的方法。
如果这两个方法都在同一个类中,您可以将dbContext分配给私有属性并使用它,而不是为每个方法创建一个新的dbContext(并取出Using语句,否则它将在离开它们时处置上下文)。
然而,我同意上面的Gert -你的解决方案的结构是什么使这对你来说很困难。DbContext是一个工作单元存储库,应该这样对待。当我们创建库的库时,它就变成了乌龟,然后就疯狂了。
我理解你的观点,所以我怎么说Gert如果你有一个很好的例子,这将是一个很好的帮助,也许这些部分的添加,删除他们应该在存储库内,这样我可以重用。