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

可能使用外观模式和视图访问外观,这来控制事务更好,但我不知道我需要帮助,感谢回复

C# EF + Repository + UnitOfWorkk pattern

如果在两个方法中都要处理上下文,我真的不知道有什么办法可以做到。我可能会写另一个同时做这两件事的方法。

如果这两个方法都在同一个类中,您可以将dbContext分配给私有属性并使用它,而不是为每个方法创建一个新的dbContext(并取出Using语句,否则它将在离开它们时处置上下文)。

然而,我同意上面的Gert -你的解决方案的结构是什么使这对你来说很困难。DbContext是一个工作单元存储库,应该这样对待。当我们创建库的库时,它就变成了乌龟,然后就疯狂了。

我理解你的观点,所以我怎么说Gert如果你有一个很好的例子,这将是一个很好的帮助,也许这些部分的添加,删除他们应该在存储库内,这样我可以重用。