为了账号安全,请及时绑定邮箱和手机立即绑定

为什么数据库数据没有更新,但对象更新了并且没有错误?

为什么数据库数据没有更新,但对象更新了并且没有错误?

C#
开心每一天1111 2023-09-09 17:30:33
我有这个银行 ATM 模型应用程序,它实现了一些领域驱动设计架构和工作单元模式。这个应用程序有3个基本功能:查看余额订金提取这些是项目层:ATM.Model(领域模型实体层)namespace ATM.Model{public class BankAccount{    public int Id { get; set; }    public string AccountName { get; set; }    public decimal Balance { get; set; }    public decimal CheckBalance()    {        return Balance;    }    public void Deposit(int amount)    {        // Domain logic        Balance += amount;    }    public void Withdraw(int amount)    {        // Domain logic        //if(amount > Balance)        //{        //    throw new Exception("Withdraw amount exceed account balance.");        //}        Balance -= amount;    }}}namespace ATM.Model{public class Transaction{    public int Id { get; set; }    public int BankAccountId { get; set; }    public DateTime TransactionDateTime { get; set; }    public TransactionType TransactionType { get; set; }    public decimal Amount { get; set; }}public enum TransactionType{    Deposit, Withdraw}}
查看完整描述

2 回答

?
慕神8447489

TA贡献1780条经验 获得超1个赞

这里问题的核心是,AppDbContext正在创建两个实例来执行一项操作。更改是在一个实例中进行的,并SaveChanges在另一实例上调用。显然,它没有反映在底层数据库中。


我们现在将从下到上逐步检查您的代码。


在ATM.ConsoleUICore.Program.Main()方法中,注意以下代码:


AccountService accountService = new AccountService();

...

...

...

accountService.DepositAmount(bankAccount, 50);

您正在创建 的实例AccountService。在 的构造函数中AccountService,您将创建一个实例,UnitOfWork如下所示:


private readonly UnitOfWork uow;

public AccountService()

{            

    uow = new UnitOfWork();

}

在 的构造函数中UnitOfWork,您正在创建 的一个实例AppDbContext(派生自DbContext)。

您还拥有BankAccounts财产,它是一个实例,RepositoryBankAccount如下所示:


private readonly AppDbContext db;

public UnitOfWork()

{

    db = new AppDbContext();

}

...

...

...

private RepositoryBankAccount _BankAccounts;

public RepositoryBankAccount BankAccounts

{

    get

    {

        if (_BankAccounts == null)

        {

            _BankAccounts = new RepositoryBankAccount();

        }

        return _BankAccounts;

    }

}

现在问题...


在 的构造函数中RepositoryBankAccount,您再次创建 的实例,AppDbContext如下所示:


public AppDbContext context { get; }

public RepositoryBankAccount()

{

    context = new AppDbContext();

}

实际上,您假装您在一个UnitOfWork实例下的操作正在作为一个数据库事务执行。但是,当您在存储库中创建不同的实例时AppDbContext,情况并非如此。您的工作单元与存储库分离。你必须将它们连接起来。它应该是AppDbContext到处相同的实例。


那么,解决办法是什么呢?


不要在任何存储库中创建 的实例AppDbContext。相反,从工作单元注入现有实例。


public AppDbContext context { get; }


public RepositoryBankAccount(AppDbContext appDbContext)//<==Inject the AppDbContext

{

    context = appDbContext;//<==Do NOT create new instance here; assign the injected instance.

}

然后,在您的UnitOfWork班级中,更改属性,BankAccounts如下所示:


private RepositoryBankAccount _BankAccounts;

public RepositoryBankAccount BankAccounts

{

    get

    {

        if (_BankAccounts == null)

        {

            _BankAccounts = new RepositoryBankAccount(db);//<==Note that `db` means `AppDbContext` is injected

        }

        return _BankAccounts;

    }

}

顺便说一句,避免所有这些不必要的包装纸。

看看这个答案,它解释了为什么不需要这样的包装器。


以防万一您决定继续现有的设计,我已经在上面建议了一个解决方案。


此外,我建议您的一个工作单元应该是一个数据库事务。因此,数据库事务在您创建工作单元实例时开始,并在您处置它时结束(提交或回滚)。要么所有内容都刷新到数据库,要么什么都不刷新。在此期间发生的所有事情都应该是一个数据库事务的一部分。如果出现异常,则一起回滚工作单元。


查看完整回答
反对 回复 2023-09-09
?
繁华开满天机

TA贡献1816条经验 获得超4个赞

对任何数据库事务尝试这种格式。创建多个实例


public RepositoryTransaction()

    {

        context = new AppDbContext();

    }

只是意味着您每次创建实例并且它不会保存到数据库中。


  using(AppDbContext db = new AppDbContext())

{

   var transaction = new Transaction()

        {

            BankAccountId = bankAccount.Id,

            Amount = amount,

            TransactionDateTime = DateTime.Now,

            TransactionType = TransactionType.Deposit

        };


    // save them back to the database

    //Add new Employee to database

         db.Transactions.InsertOnSubmit(transaction);


         //Save changes to Database.

         db.SubmitChanges();

}



     using(AppDbContext db = new AppDbContext())

    {

        // get the record

        Transaction dbProduct = db.Transactions.Single(p => p.BankAccountId == 1);


    // set new values

    dbProduct.TransactionDateTime = DateTime.Now; 

    dbProduct.TransactionType =  TransactionType.Deposit;


    // save them back to the database

    db.SubmitChanges();

}


查看完整回答
反对 回复 2023-09-09
  • 2 回答
  • 0 关注
  • 118 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信