如何编写与数据库无关的 .NET Core 应用程序?

Dej*_*jan 5 c# ado.net sqlclient database-agnostic .net-core

我正在努力将控制台应用程序从 .NET Framework 4.6.2 移植到 .NET Core 2.0。该应用程序需要连接到一个数据库,该数据库的平台在编译时未知。在完整的框架中,这可以通过使用DbProviderFactories.NET Core 2.0 中不再存在的机制轻松实现。

首先,我想我可以简单地DbProviderFactory自己动态加载相应的内容,使用类似于以下的代码:

public static DbProviderFactory GetFactory(string providerInvariantName)
{
    Type type = Type.GetType(dbProvider.Type);
    if (null != type)
    {
        FieldInfo field = type.GetField("Instance", BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public);
        if (null != field && field.FieldType.IsSubclassOf(typeof(DbProviderFactory)))
        {
            object value = field.GetValue(null);
            if (value != null)
            {
                return (DbProviderFactory)value;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

正如在这个图书馆中所做的那样。只要DbProviderFactory在编译时引用包含 的程序集,此代码就可以正常工作(这违背了动态加载的目的)。

我试图直接放入System.Data.SqlClient.dll应用程序的文件夹中,但是该Instance字段是null因为这似乎只是不同runtimes程序集的存根实现。当静态引用时,编译器会生成一个.deps.json指向这些文件的详细文件。这里只是为了给人留下印象而做的一个小改动:

...
"runtime.win-x64.runtime.native.System.Data.SqlClient.sni/4.4.0": {
  "type": "package",
  "serviceable": true,
  "sha512": "sha512-38ugOfkYJqJoX9g6EYRlZB5U2ZJH51UP8ptxZgdpS07FgOEToV+lS11ouNK2PM12Pr6X/PpT5jK82G3DwH/SxQ==",
  "path": "runtime.win-x64.runtime.native.system.data.sqlclient.sni/4.4.0",
  "hashPath": "runtime.win-x64.runtime.native.system.data.sqlclient.sni.4.4.0.nupkg.sha512"
},
"runtime.win-x86.runtime.native.System.Data.SqlClient.sni/4.4.0": {
  "type": "package",
  "serviceable": true,
  "sha512": "sha512-YhEdSQUsTx+C8m8Bw7ar5/VesXvCFMItyZF7G1AUY+OM0VPZUOeAVpJ4Wl6fydBGUYZxojTDR3I6Bj/+BPkJNA==",
  "path": "runtime.win-x86.runtime.native.system.data.sqlclient.sni/4.4.0",
  "hashPath": "runtime.win-x86.runtime.native.system.data.sqlclient.sni.4.4.0.nupkg.sha512"
},
...
Run Code Online (Sandbox Code Playgroud)

这不是别人可以手动输入的。

那么在 .NET Core 中开发与数据库无关的应用程序的好方法是什么?