C#EF + Repository + UnitOfWorkk模式

时间:2014-05-08 18:18:54

标签: c# entity-framework

我有一个关于架构的问题,这是我的场景,我正在使用EF构建分层解决方案,所以我为我的实体做了存储库而UnitOfWork管理我的存储库是完美的我把控制方法和事务工作,我的业务实体消耗工作单元,我开始使用我的业务规则,但是我有一个问题,例如,有一种方法我需要使用两种业务方法来避免代码重复并在同一个事务中工作我怎么能这样做?

下面的业务方法:

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

也许使用外观模式和视图访问外观,这来控制交易更好,但我不知道我需要帮助感谢回复

3 个答案:

答案 0 :(得分:1)

如果你在两种方法中处理上下文,我真的没有办法实现它。我可能只会编写另一种方法来完成这两件事。

答案 1 :(得分:0)

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

但是,我同意Gert的观点 - 您的解决方案的结构正是让您难以理解的。 DbContext是一个工作单元存储库,应该这样对待。当我们制作存储库的存储库时,它就会变成乌龟一直向下,而疯狂就是这样。

答案 2 :(得分:0)

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