MetaDapper:使用正確的工具輕鬆實現數據映射和轉換

已發表: 2022-03-11

數據轉換、翻譯和映射絕不是火箭科學,但絕對是乏味的。 即使是簡單的數據轉換任務(例如,將 CSV 文件讀入類實例列表)也可能需要大量代碼。 儘管所有這些任務有很多共同點,但它們都“只是不同而已”,需要自己的數據轉換方法。

在我們構建的幾乎每個系統中,我們都會發現自己需要將數據從一種形式轉換為另一種形式,無論是從現有數據存儲中導入數據,處理來自傳入流的數據,還是從一種格式轉換為另一種格式以供內部使用。處理或將數據轉換為所需的輸出格式。

每次我們這樣做時,這項任務似乎都與我們之前多次完成的任務非常相似,但又存在足夠的差異,需要我們重新進行數據映射過程,主要是從頭開始。

此外,隨著最流行的格式和訪問它們的技術不斷發展,新的格式和技術被引入並流行起來,程序員有義務不斷學習新的數據轉換和映射技術、庫、API 和框架。 隨著數據科學服務的不斷發展和演變,對專用工具的需求也在擴大。

儘管您可以利用 AutoMapper(將數據從一個對象映射到另一個對象)或 Resharper(重構現有代碼)等工具,但無論您做什麼,代碼編寫起來都很乏味,並且始終需要維護。 然後你必須想出一個跨域翻譯處理的解決方案——比如將內部代碼和鍵值轉換為另一個層或系統的值,將空值轉換為默認值,類型轉換等。

驗證有類似的問題,這些問題可以通過 DataAnnotations 和 jQuery Validation 插件等技術以及大量自定義驗證代碼來解決。 這些技術的細微差別可能非常微妙。

作為一名高級數據科學家,你告訴自己“一定有更好的方法”。 嗯,事實上,有。 這就是本數據映射教程的內容。

介紹 MetaDapper 數據映射工具

MetaDapper 是一種數據映射工具,可使用各種數據映射技術幫助改進此過程。

MetaDapper 是一個 .NET 庫,旨在最大程度地簡化和簡化數據轉換過程。

MetaDapper 通過以下方式促進數據轉換:

  • 將數據轉換過程的可重複樣板部分與每個數據轉換任務獨有的那些方面分離。
  • 提供易於使用、直觀的用戶界面,用於指定任意複雜度的映射和轉換規則。

MetaDapper 將邏輯映射(模式、數據轉換和驗證)與物理數據映射(與各種文件格式和 API 的轉換)分開。 邏輯映射具有一組強大的功能,並允許您使用自己的方法來處理非常特定的需求。 物理映射包括一組豐富的支持格式,這些格式正在不斷擴展。 為了配置映射,提供了 MetaDapper Configurator; 一個簡單易用的 Windows 可執行文件,用於創建和編輯映射,以及執行它們以進行測試或一次性轉換。

將類實例列表轉換為 XML 或 CSV 文件、填充 SQL 數據庫記錄、生成用於填充表的 SQL 腳本、創建電子表格等等,所有這些都使用通常可以在幾秒鐘內創建的相同配置文件完成。

要將 MetaDapper 包含在您的 .NET 程序中,您只需:

  • 添加對庫的引用
  • 實例化 MetaDapper 引擎
  • 執行映射,指定源讀取器(和任何參數)、目標寫入器(和任何參數)和您的配置文件。

成功後,作者將輸出轉換後的數據。 出錯時,異常會返回詳細的錯誤信息,以便您拒絕數據或調整配置。

這是一個簡短的數據映射示例:

 List<MyClass> result; try { // Instantiate the MetaDapper library. var log = new Log(); var cultureInfo = new CultureInfo("en-US"); var md = new MetaDapper.Engine.MetaDapper(log, cultureInfo); using (var inputStream = new StreamReader(@"C:\myfile.csv")) { md.MapData( new CsvReaderParameters { Log = log, CultureInfo = cultureInfo, InputStream = inputStream.BaseStream, InputEncoding = Encoding.ASCII, FirstRecordIsHeader = false }, new PublicPropertiesWriterParameters { Log = log, CultureInfo = cultureInfo }, @"C:\MyMetaDapperConfiguration.xml", false, out result); } } catch (Exception) { throw; }

MetaDapper “配置器”

MetaDapper 配置器提供了一種直觀地完成定義數據結構和轉換/映射規則的步驟的方法。 配置器使您能夠創建、編輯和執行配置(即,用於測試或一次性轉換)。

MetaDapper 的配置器致力於盡可能多地自動化該過程。 例如,在指定字段映射時,源字段和目標字段會在可能的情況下使用名稱匹配自動匹配。 此外,在為包含元數據的數據源創建記錄定義時,可以通過指向數據源來自動填充字段定義。

創建後,記錄定義會維護其與創建它的數據源的鏈接(如果有),因此如果數據源模式隨後發生更改,它可以自動更新。 為幾乎沒有或沒有元數據的數據源配置記錄定義時,如果另一個類似的數據源包含元數據,則可以復制該記錄定義(連同其元數據),作為新記錄定義和然後可以進行編輯以反映兩個數據源之間可能存在的任何差異。 在多個數據源的架構和元數據相同的情況下,一個記錄定義可用於所有數據源。

簡化數據轉換過程

讓我們更詳細地了解數據轉換過程中固有的一些挑戰,以及 MetaDapper 為開發人員促進和簡化這些挑戰的方式。

將源數據映射到目標數據

當在維護過程中更改內部或外部結構時,任何依賴這些結構的映射代碼也可能需要調整。 這是一個經常需要維護工作的領域,因此無論您使用哪種解決方案,都需要評估維護成本。 例如,如果從 Sale 類中刪除了 TotalSale 屬性,則需要相應地調整任何相關的映射分配。

使用 MetaDapper,更新映射可能只需幾秒鐘。 例如,對於類類型,只需單擊“從類中導入字段定義”按鈕即可將字段刷新為新編譯的定義:

將源數據映射到目標數據

類型轉換

某些類型轉換,例如 Date/Time 和 Number 類型轉換,對宿主環境的國際設置很敏感(除非在代碼中明確指定)。 因此,在具有不同國際設置的新服務器上部署應用程序可能會破壞沒有考慮到這一點的代碼。 例如,日期值“1-2-2014”在美國設置的機器上將解釋為 2014 年 1 月 2 日,但在英國設置的機器上解釋為 2014 年 2 月 1 日。 MetaDapper 支持所有隱式 .NET 轉換,並允許在轉換過程中對值進行複雜的重新格式化。 此外,可以在 MetaDapper 讀取器、寫入器和映射引擎中指定單獨的(即獨立的)國際設置。

複雜的默認值

有時,需要訪問其他系統或需要復雜編碼來確定默認值的特定業務規則。 MetaDapper 允許將任意數量的自定義委託方法註冊到引擎並用於提供默認值、執行自定義數據轉換以及提供自定義字段驗證。

條件驗證規則

有條件地要求字段值(甚至它們的有效值依賴於其他字段的值)的情況並不少見。 例如,合作夥伴名稱和合作夥伴社會保障代碼字段可以留空,但如果提供了合作夥伴名稱,則必須提供合作夥伴社會保障代碼(可能還有其他字段)。 這種類型的條件驗證很複雜,在自定義代碼中很容易出錯。 相比之下,MetaDapper 允許輕鬆配置這種數據映射關係。 具體來說,記錄定義中的字段列表可以在條件強製字段組中列出:

這些示例數據字段之間的關係很容易使用 MetaDapper 等數據映射工具進行配置。

然後在映射中,該組可以與任何字段相關聯,如果該字段不為空,則反過來需要提供該組中的所有字段。 例如:

此數據映射示例顯示了使用 MetaDapper 與自定義代碼相比更容易配置。

跨域轉換映射值

源數據可能包含不一致的值。 例如,稱呼字段可能包含“先生”、“先生”、“先生”、“先生”或“M”以及所有女性等價詞。 或者貨幣字段可能包含“$”之類的值,而您的目標格式需要“USD”。 產品代碼是可能需要從一個系統轉換到另一個系統的值的另一個示例。 MetaDapper 允許規範可重用的“同義詞列表”,可用於在映射期間轉換值。

定義後,您可以指定同義詞組以在任何相關字段映射中使用它:

這種數據映射技術可以很好地處理社會保障示例中的同義詞。

基於值格式和復雜計算的映射

可能需要使用來自一個或多個字段的值來格式化新值。 例如,源值可能需要用常量修飾(例如sale.PriceEach = "$" + priceEach; )或者可能需要使用多個字段來生成值(例如sale.Code = code1 + “_” + code2; )。

MetaDapper 提供格式化/模板功能,允許您使用當前記錄中的任何字段構建值,包括字段的子字符串部分或常量值。 格式化後,該值將轉換為指定的目標類型(順便說一下,它不需要是字符串)。

類似地,可以在映射期間執行複雜的計算,對字段值和常數的任意組合使用一整套數學運算符和函數。

驗證規則

可以在映射中註冊和使用自定義驗證委託。 以下是驗證字段值是否為整數的自定義方法示例(不將字段的數據類型設為整數):

 private static bool ValidateIsInteger( Log log, CultureInfo cultureInfo, object value, ref List<ErrorInfo> errors) { try { Convert.ToInt32(value); } catch (Exception) { return false; } return true; }

該方法將在實例化 MetaDapper 時註冊。 然後它可以很容易地應用於任何字段映射定義:

MetaDapper 定義說明

分組、排序和過濾

分組和排序操作通常可以在數據庫查詢中處理,但並非所有數據源都是數據庫。 因此,MetaDapper 支持可在內存中執行的複雜分組和排序操作的配置。

在可能只需要部分源數據的情況下,從非數據庫源中過濾可能非常複雜,難以實現和維護。 MetaDapper 支持使用布爾運算符為每條記錄的任意數量的字段評估配置複雜的過濾器,並根據需要進行任意深度的操作嵌套。 例如:

複雜過濾器在此處顯示的數據映射過程中起著重要作用。

上述過濾器等價於以下 C# 代碼:

 if (sale.TransactionID > “0” AND sale.Currency == “USD” AND (sale.Amount > “3” || sale.Amount == “1”)

嵌套映射

一些映射需要多次傳遞才能完成數據轉換過程。 一些示例包括需要前綴或匯總記錄的數據、需要根據字段值或文檔結構進行不同映射的數據,或者只是為了隔離複雜映射的不同階段(即翻譯名稱、類型轉換等)。 為此,MetaDapper 支持任何深度級別的嵌套映射。

格式與結構

作為一種數據映射和轉換工具,MetaDapper 的構建允許使用內部讀取器和寫入器接口讀取或寫入幾乎任何數據格式。 這允許創建非常輕量級的讀取器/寫入器類,並且只關注特定於格式的細微差別。

讀者和作者的行為也盡可能聰明和靈活。 例如,XML 讀取器和寫入器使用 XPath 來指定在 XML 文件中檢索或寫入數據的位置。 相同的配置還可用於讀取和寫入,例如,從非 XML 格式(如 CSV 文件)讀取和寫入,在這種情況下,XPath 值將被簡單地忽略。 同樣,如果將不包含 XPath 設置的配置與 XML 讀取器或寫入器一起使用,則會生成錯誤。

是的。 正確的。 當然。 (一些真實的數據映射示例)

你持懷疑態度。 而且我不怪你。 軟件工具很少是他們聲稱的那樣。 因此,這裡有一些實際示例,其中 MetaDapper 已被用於提供運營收益。

一家提供醫療保險管理軟件的公司的客戶不想填寫 Web 表格,但想在電子表格中提供他們的數據。 使用 MetaDapper,將上傳的電子表格讀入內存、清理數據、驗證記錄並將結果存儲在其數據庫中。 他們能夠接受來自客戶的 Excel 文件,而無需使用 MetaDapper 進行任何人工驗證,並為他們發布的每個電子表格模板輕鬆創建配置文件。

一家大型天然氣公司有一個內部應用程序,並希望其管理用戶能夠下載 Excel 格式的報告。 報告格式可能會定期更改。 MetaDapper 促進了從他們的數據庫中生成 Excel 工作表。 更新 Excel 格式只需要更新 MetaDapper 配置文件,無需任何代碼更改或重新編譯。

一家提供資產管理軟件的公司需要一種解決方案,以生成與客戶相關的會計數據包格式的財務數據,以便導入這些系統。 使用 ORM 包裝器開發了通用會計數據查詢,並使用 MetaDapper 對數據進行排序、過濾和映射到每個客戶所需的模式和格式。 為每個客戶製作一個或多個 MetaDapper 配置,這已成為新客戶的主要銷售功能。 該產品可以在幾分鐘內配置(使用 MetaDapper)以支持任何自定義或標準會計包格式,因此每次新銷售都包含與基本和現有系統的集成。 同一家公司在各種軟件集成項目中使用 MetaDapper,映射和轉換數據以及在其係統之間轉換內部代碼。

一家大型汽車經銷商需要將一些 Excel 格式的銷售報告添加到他們的一個應用程序中。 報告在不到一個小時的時間內被添加到應用程序中——從開始到結束。

開發人員需要一個與另一個網站上使用的集合相同的美國州表。 MetaDapper 用於從該站點挖掘數據並在幾分鐘內生成用於填充他的表的 SQL 腳本。

這些只是 MetaDapper 作為數據映射工具經過驗證的實用性和價值的幾個示例。

包起來

開始更一般地考慮數據轉換並開始考慮具有業務規則和無限有用性的數據集需要精神上的跳躍。 MetaDapper 是一個促進和促進這種觀點的框架。

無論您是使用 MetaDapper,另一種技術,還是推出自己的數據映射解決方案,這都是對數據轉換項目中的一些複雜性和隱藏成本的介紹。 我希望你能從中受益。

(有關 MetaDapper 的更多信息,請通過 [email protected] 聯繫 MetaDapper 團隊。)