繼續分享升級 .NET 8 踩坑心得,用以下程式重現問題:

using System;
using System.Data.SqlClient;

var obj = new SomeClass();

var typeNames = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(assembly => assembly.GetTypes())
            .Where(type => !type.IsInterface && typeof(IFoo).IsAssignableFrom(type))
            .Select(type => type.Name)
            .Distinct();

Console.WriteLine($".NET {Environment.Version}");   
Console.WriteLine(string.Join(Environment.NewLine, typeNames));

public interface IFoo {}

public class SomeClass : IFoo
{
    public SomeClass() {
        var cn = new SqlCommand();
    }
}

.NET 7 OK、.NET 8 出現 Could not load type 'SqlGuidCaster' from assembly 'System.Data.SqlClient, Version=4.6.1.5, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field. 錯誤:

爬文查到原因,System.Data.SqlTypes.SqlGuid 定義早先由 struct SqlGuid{ byte[] _value; } 改成 struct SqlGuid{ Guid? _value; },這導致 .NET 8 新加的轉換 Value Type 動作出錯。好消息是 Microsoft.Data.SqlClient 在 5.2.0-preview 修復了這個問題;System.Data.SqlClient 也有相同 Issue,但引用 SQL Server Driver 開發主管的說法:System.Data.SqlClient, is unlikely to receive further updates, much less those that are only for fixing Reflection issues. (System.Data.SqlClient 已停更,何況是 Relfection 這類次要問題)

㤦用 dotnet add package Microsoft.Data.SqlClient --prerelease 安裝 Microsoft.Data.SqlClient 5.2.0-preview 版本,實測問題可解決:

專案目前還有一些第三方套件依賴 System.Data.SqlClient,全面改用 Microsoft.Data.SqlClient 工程不小,避開 Relection 改用其他做法是較可行。

最後整理 System.Data.SqlClient 的現況與未來發展。引用 .NET 部落格 2019 的文章 Introducing the new Microsoft.Data.SqlClient 對 System.Data.SqlClient 未來的規劃:

It means the development focus has changed. We have no intention of dropping support for System.Data.SqlClient any time soon. It will remain as-is and we will fix important bugs and security issues as they arise. If you have a typical application that doesn’t use any of the newest SQL features, then you will still be well served by a stable and reliable System.Data.SqlClient for many years.

However, Microsoft.Data.SqlClient will be the only place we will be implementing new features going forward. We would encourage you to evaluate your needs and options and choose the right time for you to migrate your application or library from System.Data.SqlClient to Microsoft.Data.SqlClient.

在 Microsoft.Data.SqlClient 推出後,System.Data.SqlClient 只會針對重大 Bug 及安全問題做更新,只要不用新功能,System.Data.SqlClient 還可以用很多年沒問題。新功能將只會加入 Microsoft.Data.SqlClient,建議選擇適當時機從 System.Data.SqlClient 換成 Microsoft.Data.SqlClient。

時代的巨輪向來不等人,只會輾人。還在用 System.Data.SqlClient 的專案要有心理準備,「新功能沒有,小問題不修,還能繼續用,早換早解脫」將是未來幾年的寫照。

SqlGuidCaster issue after upgrade to .NET 8 and roadmap of System.Data.SqlClient.


Comments

# by Eason

今天我升級了套件 Microsoft.Data.SqlClient 3.0.0 => Microsoft.Data.SqlClient 5.1.4 取JWT Token時候會壞在下列這行 _httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.Name) 原因應該是Microsoft.Data.SqlClient 5.1.4相依性套件有用到ClaimTypes.Name 造成壞掉 完全劇坑,覺得這應該是官方BUG

Post a comment