[英]Entity Framework : how to catch any error
我正在嘗試將數據插入具有很多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)
)
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);
});
嘗試向表中添加數據時,代碼缺少列,因此無法插入數據庫。 我對此並不了解,也沒有收到“ NOT NULL”錯誤,就像我在SQL數據庫中看到的那樣。
var source = new Customer();
source.FirstName = "Joe"; // missing Last Name and Address
_context.Customer.Add(source);
所以我添加了以下代碼。 這解決了問題,但是如果出現任何數據庫錯誤,並發,錯誤的數據類型等,我將如何使它失敗?
try
{
_context.SaveChanges();
}
catch (DbUpdateException e)
{
}
以下方法不起作用:方法1和2:實現這些方法后,不再出現我們想要的not null錯誤。
try
{
_context.SaveChanges();
}
catch (Exception e)
{
}
try
{
_context.SaveChanges();
}
catch
{
}
try {
var source = new Customer();
source.FirstName = "Joe";
_context.Customer.Add(source);
_context.SaveChanges();
}
catch (Exception ex) {
// ...
}
您可以在catch塊中檢查異常的類型,以獲取確切的異常消息,例如
try
{
//Your code here
}
catch (Exception ex)
{
if (ex.GetType() == typeof(DbEntityValidationException))
{
//Exception thrown from System.Data.Entity.DbContext.SaveChanges when validating entities fails.
}
else
if (ex.GetType() == typeof(DbUnexpectedValidationException))
{
//Exception thrown from System.Data.Entity.DbContext.GetValidationErrors when an
//exception is thrown from the validation code.
}
else
{
//All remaining exception here
}
}
或者您可以為每種異常類型使用不同的catch塊
try
{
//Your code here
}
catch (DbEntityValidationException de_ex)
{
//Exception thrown from System.Data.Entity.DbContext.SaveChanges when validating entities fails.
}
catch (DbUnexpectedValidationException du_ex)
{
//Exception thrown from System.Data.Entity.DbContext.GetValidationErrors when an
//exception is thrown from the validation code.
}
catch (Exception ex)
{
//All remaining exception here
}
DbContext.SaveChanges描述了您可能期望的異常。 確定要捕獲的異常,而不要捕獲的異常。
如果不確定在什么情況下會遇到哪些異常,請使用調試器和一些測試代碼來找出您可能期望的異常:
// TODO: create one of your error conditions
try
{
_context.SaveChanges();
}
catch (Exception e)
{
Console.WriteLine(e.GetType()); // what is the real exception?
}
當您知道可以預期的異常以及您真正可以處理的異常時,請編寫最終代碼:
try
{
_context.SaveChanges();
}
catch (DbUpdateException e)
{
// handle the update exception
}
catch (DbEntityValidationException e)
{
// handle the entity validation exception
}
catch (...)
您可能不會捕獲System.NotSupportedException,因此您的代碼應僅使用受支持的LINQ語句。
請記住, DbSets
中的DbContext
代表數據庫中的表。 DbSets
的類表示表中的一行:非虛擬屬性表示表中的列,表之間的關系表示為虛擬屬性。
設計這些數據庫表是因為您想解決問題。 顯然,在您的解決方案中,FirstName / LastName等不為null很重要。
您可能會將DbContext的用法包裝到一個類中,該類隱藏了您使用實體框架保留數據的方法,而不是例如Dapper或任何較低級別的方法來查詢和更新數據。
很多時候,這個包裝類被稱為Repository
類:你的用戶Repository
不知道,真的不關心,您在哪里如何保存你的數據:SQL? 蒙戈? 甚至是CSV文件?
擁有一個Repository
類的Repository
是,如果您決定更改表布局,或者如果您決定將查詢之一更改為存儲過程,或者如果您決定將數據存儲為CSV,則將最小,用戶甚至不會注意到變化
在您的存儲庫中,您將具有查詢人員,添加/刪除/更新人員等功能。您早先決定解決方案不應接受具有空名稱的人員。
您的解決方案不依賴於如何保存數據。 因此,您的解決方案不應取決於您的存儲庫是否檢查名稱是否為null或nt。
考慮在調用SaveChanges之前檢查數據有效性 。 在這種情況下:檢查名字,姓氏等是否確實不為空。 您的代碼將
通過使用以下代碼,您可以為DbEntityValidationException
創建更加用戶友好的消息:
try
{
_context.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
var sb = new StringBuilder();
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
sb.AppendLine(string.Format("Property: {0} Error: {1}",
validationError.PropertyName,validationError.ErrorMessage));
}
}
throw new Exception(sb.ToString(), dbEx);
}
然后,您可以在更高級別捕獲此新的Exception
。 要捕獲其他異常,可以使用單獨的catch
塊。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.