2 c# error-handling entity-framework .net-core .net-core-2.0
我正在尝试将数据插入到具有很多not null约束的 SQL Server 表中:
CREATE TABLE [dbo].[Customer]
(
[CustomerId] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [varchar](255) NOT NULL,
[LastName] [varchar](255) NOT NULL,
[AddressLine] [varchar](255) NOT NULL
CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED ([CustomerId] ASC)
)
Run Code Online (Sandbox Code Playgroud)
EF代码:
public virtual DbSet<Customer> Customer { get; set; }
modelBuilder.Entity<Customer>(entity =>
{
entity.Property(e => e.FirstName)
.HasMaxLength(255)
.IsRequired()
.IsUnicode(false);
entity.Property(e => e.LastName)
.HasMaxLength(255)
.IsRequired()
.IsUnicode(false);
entity.Property(e => e.AddressLine)
.HasMaxLength(255)
.IsRequired()
.IsUnicode(false);
});
Run Code Online (Sandbox Code Playgroud)
尝试向表中添加数据时,代码缺少列,因此无法插入数据库。不知道这一点,也没有收到“NOT NULL”错误,就像我在 SQL 数据库中看到的那样。
var source = new Customer();
source.FirstName = "Joe"; // missing Last Name and Address
_context.Customer.Add(source);
Run Code Online (Sandbox Code Playgroud)
所以我添加了以下代码。这解决了这个问题,但是我怎么会在任何数据库错误、并发、错误的数据类型等上失败。
try
{
_context.SaveChanges();
}
catch (DbUpdateException e)
{
}
Run Code Online (Sandbox Code Playgroud)
以下不起作用: 方法 1 和 2:当这些被实现时,非空错误不再像我们想要的那样出现。
try
{
_context.SaveChanges();
}
catch (Exception e)
{
}
try
{
_context.SaveChanges();
}
catch
{
}
Run Code Online (Sandbox Code Playgroud)
DbContext.SaveChanges描述了您可能期望的异常。决定要捕获哪些异常,哪些不捕获。
如果您不确定在什么情况下会遇到哪些异常,请使用调试器和一些测试代码来找出您实际可能会遇到哪些异常:
// TODO: create one of your error conditions
try
{
_context.SaveChanges();
}
catch (Exception e)
{
Console.WriteLine(e.GetType()); // what is the real exception?
}
Run Code Online (Sandbox Code Playgroud)
当您知道可以预期哪些异常以及您真正可以处理哪些异常时,请编写最终代码:
try
{
_context.SaveChanges();
}
catch (DbUpdateException e)
{
// handle the update exception
}
catch (DbEntityValidationException e)
{
// handle the entity validation exception
}
catch (...)
Run Code Online (Sandbox Code Playgroud)
您可能不会捕获 System.NotSupportedException,您的代码应该只使用受支持的 LINQ 语句。
请记住,DbSetsin yourDbContext代表数据库中的表。中的类DbSets表示表中的一行:非虚拟属性表示表中的列,表之间的关系表示为虚拟属性。
您设计这些数据库表是因为您想解决一个问题。显然,在您的解决方案中,名字/姓氏等不为空很重要。
您可能会将 DbContext 的用法包装到一个类中,该类隐藏您使用实体框架来保存数据,而不是例如 Dapper 或任何较低级别的方法来查询和更新数据。
这个包装类经常被称为一个Repository类:你的用户Repository不知道,也真的不在乎,你如何以及在哪里保存数据:SQL?蒙哥?甚至可能是一个 CSV 文件?
拥有一个Repository类的好处是,如果您决定更改表布局,或者如果您决定将其中一个查询更改为存储过程,或者如果您决定将数据存储在 CSV 中,则更改将是最小的用户甚至不会注意到变化
在您的存储库中,您将拥有查询人员、添加/删除/更新人员等的功能。您之前决定您的解决方案不应接受具有空名称的人员。
您的解决方案不依赖于数据的保存方式。因此,您的解决方案不应取决于您的存储库是否检查您的名称是 null 还是 nt。
考虑在调用 SaveChanges 之前检查数据有效性。在这种情况下:检查名字、姓氏等是否确实不为空。您的代码将