2017-08-09 100 views
0

背景
與英法的核心代碼第一種方法,驗證是強大和簡單:https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/validation實體框架的核心化異常處理分貝第一

與數據庫的第一種方法,它似乎像任何驗證正在發生由幕後數據庫時調用dbcontext.SaveChanges();。更糟的是,這些異常是模糊的和完全沒有幫助,例如,SqlException: String or binary data would be truncated可以拋出,如果實體的任何的字符串屬性的任何有太多的字符(我們是一個傳統的應用程序充滿了char(10)和這樣),或者即使是一個字符串的鍵也是空的。

問題
我想知道是否有任何合理或可接受的方式來執行驗證。我發現this question這可能有助於調試,但我想執行的約束代碼

有什麼不是改變每一個汽車財產一拋出,如果它的約束得不到滿足更好的方法?

回答

1

EntityFramework Core根本不執行任何驗證。您在示例中看到的驗證規則由MVC而不是EF強制執行。 EF Core刪除驗證檢查的主要原因之一僅在於此。驗證在UI中運行,然後在EF中運行,然後在數據庫中運行,只是多餘的。因此,客戶端驗證留給前端(在這種情況下爲MVC),服務器端由數據庫引擎完成。

當您使用數據庫優先方法時,EF核心不會爲驗證生成任何註釋,因爲它無論如何都不會推理它們。這意味着您只會得到服務器端驗證,這意味着在SaveChanges期間出現錯誤。

在代碼(客戶端)中強制執行約束的唯一方法是編寫這些註釋,以便MVC可以強制執行它們或編寫自定義代碼來處理它。整個驗證機制對EF透明。

+0

,但我們正在寫一個JSON-RPC over HTTP的數據庫API來代替我們舊的存儲過程架構,而不是一個網站。所以問題仍然是,sqlserver的驗證錯誤信息完全沒有價值,我需要一個解決方案,比如擴展代碼生成工具以自動添加驗證 –

+0

無論是否爲網站,您的提供API的框架都在進行驗證,因爲EF只是不會。由於代碼中的驗證是業務邏輯,所以從數據庫中推斷它們並不容易,因此數據庫首先不會自行生成它們。您可以在從數據庫生成模型之後編寫額外的代碼,也可以嘗試在EF內核中修改代碼編寫器。雖然前者會容易得多。 – Smit

+0

主要是我擔心的約束類型就像它在db中的char(10)一樣,但屬性只是字符串,所以這些類型可以非常簡單地從數據庫中推斷出來,但我想我'我需要自己添加它 –

0

我結束了對發電機工具的僞裝擴展。由於的DbContext是一個局部類,我由具有主

public partial class DBContext{ 
    public static void Main(string[]args){ 
     DBContext context = new DBContext(); 
     var modelbuilder = new Microsoft.EntityFrameworkCore.ModelBuilder(new Microsoft.EntityFrameworkCore.Metadata.Conventions.ConventionSet()); 
     context.OnModelCreating(modelbuilder); 
     IMutableModel model=modelbuilder.Model; 
從那裏我使用LINQ到大約每個實體的屬性,並在其上的註解的各種信息轉換成 List<KeyValuePair<string,List<KeyValuePair<Regex,string>>>>其中第一對重點

一個新的類是實體名稱,值是查找和替換對的列表,用於編輯已通過相應驗證生成的代碼,每個屬性一個。然後,我所要做的就是濫用這個事實,即該工具生成<className>.cs文件中的類,並遍歷我的列表,爲每個實體源代碼文件執行替換。

我更喜歡做一些不那麼哈克,因爲我依靠格式的EF工具輸出,但它的工作原理