我目前正在为一所大学开发一个项目,为学生创建一个帐户,通过这个帐户,他们可以计算出他们的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条记录一样。这是截图:
这是我的业务层逻辑:
我的业务层调整版的类视图是:
我想从插入尝试对象中清除dbSet local而不重新启动应用程序,以便让用户更正错误并再次创建帐户。
如果我在某些方面有误导或误解,请原谅我。任何帮助将不胜感激。谢谢!
除了关于DbContext生命周期的关于卖贴的非常有效的评论,你还可以做一些事情。
如果您想对应用进行最少的更改,那么我建议您使用交易,例如
using (var transaction = dbContext.Database.BeginTransaction())
{
try
{
// Prepare POCOs to be stored
...
dbContext.SaveChanges();
transaction.Commit();
}
catch (Exception)
{
// Handle failure
}
}
如果SaveChanges()
失败,您的事务将自动回滚,并且此块中添加的所有对象将从dbContext
中删除。
您可以在EF Core或EF 6上找到有关MSDN交易的更多信息。
但是,我建议您重新考虑您的验证方案。数据验证不应该发生在数据库级别 - 验证应该在请求生命周期的早期发生,甚至可能在您创建要存储到数据库的POCO之前。