只有累積,沒有奇蹟

2019年4月24日 星期三

[.NET] 當 Dapper 遇到 SQL uniqueidentifier Type

問題 
Dapper 的輕巧與容易上手程度是大家有目共睹的,在公司中大部分專案也是選擇 Dapper 
資料庫做存取資料的動作,近期接獲同事詢問在開發時透過 Stored Procedure 存取資料庫某個 Table 中欄位資料型別為 uniqueidentifier (GUID) 一直失敗,Error 錯誤訊息為  Object must implement IConvertible ,這篇就針對此案例作簡單紀錄與分享若是有不清楚或是錯誤的地方歡迎討論予糾正

解決方法 
首先先還原案發現場,代碼如下
  1. // Query
  2. public IEnumerable<MemberModel> GetAllMember(int countryCode)
  3. {
  4. var parameters = new DynamicParameters();
  5. parameters.Add("@countryCode", countryCode, DbType.Int16);
  6. parameters.Add("@output", string.Empty, DbType.String, ParameterDirection.Output);
  7.  
  8. return Query<MemberModel>("[dbo].[usp_Member_GetAllMember]", parameters).ToList();
  9. }
  10.  
  11. protected virtual IEnumerable<T> Query<T>(string name, SqlMapper.IDynamicParameters parameters)
  12. {
  13. IEnumerable<T> result;
  14. try
  15. {
  16. using (var connection = new SqlConnection(connectionString))
  17. {
  18. result = connection.Query<T>(name, parameters, commandType: CommandType.StoredProcedure);
  19. }
  20. }
  21. catch (Exception e)
  22. {
  23. logger.LogError(e, name);
  24. throw;
  25. }
  26. return result;
  27. }
  28.  
  29. // Model
  30. public class MemberModel
  31. {
  32. public string ID { get; set; }
  33. public string Name { get; set; }
  34. }
在資料庫所要存取的 Table 設計 ID 資料型態為 uniqueidentifier,執行以上代碼會發生錯誤訊息如下
  1. 2019-04-24 18:09:13.8418||ERROR|.ctor|[dbo].[usp_Member_GetAllMember] System.Data.DataException: Error parsing column 1 (ID=d27ee4a2-146c-43f7-afc5-4e6cafe262b3 - Object) ---> System.InvalidCastException: Object must implement IConvertible.
  2. at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
  3. at Deserializece44011c-705b-4af9-bbdd-7b47377c8cc6(IDataReader )
  4. --- End of inner exception stack trace ---
取得資料後在 parsing 欄位值時發生錯誤 (Error parsing),錯誤型別為System.InvalidCastException,也就是說有抓到欄位值為 d27ee4a2-146c-43f7-afc5-4e6cafe262b3,但在 Parse 的時候轉型別失敗,遇到此情況有兩種解決方式

調整回傳欄位
在目前此 Case 可以看到回傳型別物件 MemberModel 中的 ID 欄位為字串 String,因此將 SP ID欄位回傳型別由原本的 uniqueidentifier 改為字串,在 MSSQL 中可以使用 CAST and CONVERT 進行轉換的動作,如下 
  1. select convert(nvarchar(36), ID) as ID

調整 Model
原先的欄位型態為 uniqueidentifier 對應到 C# 中就是 Guid 型別,因此有可能因為此 SP 回傳值有不能修改的情況,因此可以修改承接的 ModelName 對應的欄位 ID,由原先的 string 改為 Guid 類型,調整如下 
  1. public class MemberModel
  2. {
  3. public Guid { get; set; }
  4. public string Name { get; set; }
  5. }
調整完畢之後,即可正常執行取得資料
Enjoy Coding !!

參考
CAST and CONVERT 

Related Posts:

  • [NETCore] 在 ASP.NET Core Web API 中使用 Serilog 前言 近期專案都在嘗試 Serilog,對於使用上有點小小心得,因此整理這篇文章分享 Serilog 在 ASP.NET Core API 上的使用與設定,也接續之前 Serilog 的系列介紹文 : 傳送門 的實際應用心得,希望可以幫到有需要的朋友,若有問題或是錯誤的地方歡迎提出來一起討論或是給予指導。 ASP.NET Core logging 首先先建立新的 ASP.NET Core Web Applicat… Read More
  • [NETCore] 結構化日誌 Serilog - Events Types 和 Enrichment 前言 前兩篇分別介紹了關於 Serilog 的基礎應用與設定,這篇就來針對事件類型 Event Type 與 介紹幾個常用的 Enricher,若有問題或是錯誤的地方歡迎提出來一起討論。 Event Type 結構化日誌的好處是可以清楚的分辨"每一次"紀錄的事件,舉例來說下列簡單的代碼是透過 Serilog 寫入log 到 Console 與 File 檔案,紀錄內容是 3 筆資料 Log.Logger = new LoggerCo… Read More
  • [NETCore] 結構化日誌 Serilog - 配置設定 前言 上一篇在 結構化日誌 Serilog 初體驗 介紹了關於 Serilog 的基本操作,這篇是針對 Serilog 在 ASP.NET Core 的設定與 Config 做進一步的介紹,若有問題或是錯誤的地方歡迎提出來一起討論或是給予指導。 基本使用 首先先來回顧一下基本使用方式,在 Serilog 如果要紀錄 Log 資訊必須使用  LoggerConfiguration&n… Read More
  • [NETCore] 結構化日誌 Serilog 初體驗前言 在 .NET 使用日誌框架第一時間會想到 NLog 或是 Log4Net 兩種 Log 常使用的 Library,Serilog 是這幾年快速崛起的 Log 框架之一,Serilog 是以 Structured logging 為基礎進行設計,透過 logging API 可以輕鬆的記錄應用程式中對象屬性,方便快速進行 logging 內容進行查詢與分析,並將其紀錄內容透過 json (可指定) 的方式輸出,這篇就介紹 … Read More
  • [NETCore] ASP.NET Core 啟動異常 - HTTP Error 500.30 - ANCM In-Process Start Failure 問題  在開發專案時跳出異常訊息,錯誤訊息為  HTTP Error 500.30 - ANCM In-Process Start Failure ,這篇就針對此案例作簡單紀錄與分享,若是有不清楚或是錯誤的地方歡迎討論予糾正。 解決方法  廢話不多說,先看案發現場的錯誤畫面 執行異常的程式代碼,看起來很單純的代碼 public static void Main(s… Read More

0 意見:

張貼留言

Copyright © 2025 m@rcus 學習筆記 | Powered by Blogger

Design by Anders Noren | Blogger Theme by NewBloggerThemes.com