如何从DbContext中清除未插入的POCO? - 实体框架代码优先

问题描述 投票:0回答:1

我目前正在为一所大学开发一个项目,为学生创建一个帐户,通过这个帐户,他们可以计算出他们的GPA,访问论坛和屏幕共享。我正在使用ASP.NET MVC和ASP.NET Web Api技术。我开发了我的业务层,并制作了“经理”类,有助于为我项目的所有POCO进行数据库操作。我的所有经理类都使用来自BaseManager类的相同DbContext。我的POCO类中有一些规则可以防止数据库插入,如果信条错误的话。

当我输入这些字段时,db插入会按预期失败。但在此之后,当我插入正确的值(向不应为null的字段输入值等)时,db插入再次失败,并且尽管错误得到纠正,但同样的验证错误显示为失败尝试之前。

这是我的用户POCO课程(我正在分享我正在谈论的两个领域):

    [Table("UserTable")]
    public class User
    {
      [Required]
      [Index(IsUnique = true)]
      [MaxLength(30, ErrorMessage = "Username can not exceed 30 characters!")]
      public string Username { get; set; }

      [Required]
      [Index(IsUnique = true)]
      [MaxLength(50, ErrorMessage = "Email can not exceed 50 characters!")]
      [DataType(DataType.EmailAddress)]
      [RegularExpression("^([\\w-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}     \\.[0-9]{1,3}\\.)|(([\\w-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$")]
      public string Email { get; set; }
 }

当我检查相应POCO类的DbSet时,我看到我所有尝试过的对象也保存在本地,就像我在数据库中的2条记录一样。这是截图:

这是我的业务层逻辑:

  • 我创建了可以由任何POCO类实现的Generic Repository类。
  • 我创建了UnitOfWork类,它使用SingletonPattern创建DbSontext(在UnitOfWorkBase类中创建UnitOfWork对象),并且有2个Manager和ComplexManager类使用的方法。 1.Generic GetRepository 2.Generic GetManager
  • 我使用管理器类来定义每个POCO的方法集,如CRUD和POCO指定的方法(比如UserManager的CheckCreedientals用于登录方法)。此处进行所有数据库操作。
  • 我使用复杂的管理器类来实现需要多个管理器的方法。 (与在AccountComplexManager类中发生的createAccount方法一样,创建两个POCO类并将它们添加到数据库中。)。除了提交此处所做的更改之外,没有数据库操作。正在调用相应管理器类的方法,并且这些操作由管理器类的方法完成。 1.学生POCO 2.用户POCO
  • 我为我的经理创建了3个基类,以减少虚拟代码。 1.MotherBaseManager类:此处创建的UnitOfWork对象,由进行数据库操作的所有管理器使用。这个类也继承了接下来的2个类。它只有Context方法返回UnitOfWork对象。 2.BaseComplexManager类:ComplexManagers类的基类。有GetManager方法,以便让相应的管理器实现一些db任务和Save方法,以便在db上提交更改。 3.BaseManager类:Manager类的基类。它具有Get Repository类,以便获得用于执行db操作(如CRUD)的相应存储库类。

我的业务层调整版的类视图是:

我想从插入尝试对象中清除dbSet local而不重新启动应用程序,以便让用户更正错误并再次创建帐户。

如果我在某些方面有误导或误解,请原谅我。任何帮助将不胜感激。谢谢!

c# entity-framework repository-pattern unit-of-work
1个回答
1
投票

除了关于DbContext生命周期的关于卖贴的非常有效的评论,你还可以做一些事情。

如果您想对应用进行最少的更改,那么我建议您使用交易,例如

using (var transaction = dbContext.Database.BeginTransaction())
{
    try
    {
        // Prepare POCOs to be stored
        ...
        dbContext.SaveChanges();
        transaction.Commit();
    }
    catch (Exception)
    {
        // Handle failure
    }
}

如果SaveChanges()失败,您的事务将自动回滚,并且此块中添加的所有对象将从dbContext中删除。

您可以在EF CoreEF 6上找到有关MSDN交易的更多信息。

但是,我建议您重新考虑您的验证方案。数据验证不应该发生在数据库级别 - 验证应该在请求生命周期的早期发生,甚至可能在您创建要存储到数据库的POCO之前。

© www.soinside.com 2019 - 2024. All rights reserved.