繁体   English   中英

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

[英]How To Clear Uninserted POCO's From DbContext? - Entity Framework Code First

我目前正在为一所大学开发一个项目,该项目为学生提供了一个帐户,并可以使用该帐户计算其GPA,访问论坛和屏幕共享。 我正在使用ASP.NET MVC和ASP.NET Web Api技术。 我开发了业务层,并制作了“ Manager”类,该类有助于对项目的所有POCO进行数据库操作。 我所有的经理类都使用相同的DbContext,它来自BaseManager类。 我的POCO类中有一些规则,可防止在creedientals错误的情况下插入数据库。

当我在这些字段中输入错误时,数据库插入将按预期失败。 但是在那之后,当我插入正确的值(将值输入到不应为null的字段等)中时,db插入将再次失败,并且尽管错误已得到纠正,但还是会显示与之前失败的尝试相同的验证错误。

这是我的用户POCO类(我正在共享我正在谈论的2个字段):

    [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类实现的通用存储库类。
  • 我创建了UnitOfWork类,该类使用SingletonPattern(在UnitOfWorkBase类中创建UnitOfWork对象)创建DbSontext,并具有Manager和ComplexManager类使用的2种方法。
    • 1.通用GetRepository
    • 2.通用GetManager
  • 我使用管理器类来定义每个POCO的方法集,例如CRUD和POCO指定的方法(例如UserManager具有用于登录方法的CheckCreedientals)。 所有的数据库操作都在这里进行。
  • 我使用复杂的管理器类来实现需要多个管理器的方法。 (类似于AccountComplexManager类中发生的createAccount方法,将创建两个POCO类并将它们添加到数据库中。) 除了提交此处所做的更改外,没有数据库操作。 相应的管理器类的方法被调用,并且通过这些管理器类的方法的方法完成数据库操作。
    • 1.学生POCO
    • 2.用户POCO
  • 我为经理创建了3个基类,以减少伪代码。
    • 1.MotherBaseManager类:在此处创建并由进行数据库操作的所有管理人员使用的UnitOfWork对象。 该类也由接下来的2个类继承。 它只有Context方法可返回UnitOfWork对象。
    • 2.BaseComplexManager类:ComplexManagers类的基类。 具有GetManager方法以获取相应的管理器来实现一些数据库任务,并具有Save方法以将更改提交到数据库。
    • 3.BaseManager类:Manager类的基类。 它具有Get Repository类,以便获取用于执行数据库操作(例如CRUD)的相应存储库类。

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

我想从尝试插入的对象中清除dbSet local而不重新启动应用程序,以使用户有机会纠正他们的错误并再次创建帐户。

如果我在某个时候拼错或弄错了,请原谅我。 任何帮助将不胜感激。 谢谢!

除了Sellotape关于DbContext生命周期的非常有效的评论之外,您还可以做其他几件事。

如果您想对应用程序进行最少的更改,那么我建议您使用事务,例如

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

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

您可以在MSDN中找到有关EF CoreEF 6中事务的更多信息。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM