【问题标题】:Entity Framework Core on Windows IoT running on a RPi 3 (Console Application)在 RPi 3(控制台应用程序)上运行的 Windows IoT 上的 Entity Framework Core
【发布时间】:2017-04-09 18:06:04
【问题描述】:

我成功地将 .NET Core 控制台应用程序部署到在 Raspberry Pi 3 上运行的 Windows IoT。

应用程序从 Web 服务中提取数据并将它们存储在数据库中。我为此使用了 Entity Framework Core。

当我通过远程 powershell 启动已部署的控制台应用程序 (.exe) 时,除了访问在 Azure 上运行的数据库之外,一切正常。当应用程序尝试从数据库中读取时,它会抛出以下异常:

System.TypeInitializationException: The type initializer for 'System.Data.SqlClient.TdsParser' threw an exception. ---> System.TypeInitializationException: The type initializer for 'System.Data.SqlClient.SNILoadHandle' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'sni.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
   at System.Data.SqlClient.SNINativeMethodWrapper.SNIInitialize(IntPtr pmo)
   at System.Data.SqlClient.SNILoadHandle..ctor()
   at System.Data.SqlClient.SNILoadHandle..cctor()
   --- End of inner exception stack trace ---
   at System.Data.SqlClient.TdsParser..cctor()
   --- End of inner exception stack trace ---
   at System.Data.SqlClient.TdsParser..ctor(Boolean MARS, Boolean fAsynchronous)
   at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, TimeoutTimer timeout)
   at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, Boolean redirectedUserInstance)
   at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling)
   at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open()
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable.Enumerator.BufferlessMoveNext(Boolean buffer)
   at Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](Func`2 operation, Func`2 verifySucceeded, TState state)
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy strategy, Func`2 operation, TState state)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable.Enumerator.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.QueryMethodProvider.<_ShapedQuery>d__3`1.MoveNext()
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found)
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
   at lambda_method(Closure , QueryContext )
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass20_0`1.<CompileQueryCore>b__0(QueryContext qc)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.First[TSource](IQueryable`1 source)

应用程序文件夹中没有“sni.dll”。

使用“win8-arm”运行时部署应用程序。

  • netcoreapp2.0
  • .NET Core 2.0 SDK(运行时和工具)

有什么想法吗?

更新:

复制 System.Data.SqlClient.dll (unix lib) 并覆盖应用程序文件夹中现有的解决了该问题。请参阅下面的答案。

【问题讨论】:

  • 您是否在桌面上测试过您的应用程序?
  • 我有,一切都适用于运行时 win10-x64。我认为没有 ARM 版本的“sni.dll”,不管它是什么..
  • 你的 .Net Core 版本是什么?
  • 使用 netcoreapp2.0 和 .NET Core 2.0 SDK(工具和运行时),但也尝试使用 netcoreapp1.1 和 1.0 SDK

标签: c# .net entity-framework-core windowsiot windows-iot-core-10


【解决方案1】:

没有适用于 ARM 的本机 sni.dll 库。 (见dotnet/corefx#9064

我希望我能告诉你如何使用 System.Data.SqlClient(Linux 上使用的那个)的完全托管实现,但不幸的是它使用了 UWP 上不可用的 System.Threading.Thread...

[更新1]
等等,你没有使用 UWP。 :) 尝试让应用在运行时使用 %USERPROFILE%.nuget\packages\system.data.sqlclient\4.3.0\runtimes\unix\lib\netstandard1.3\System.Data.SqlClient.dll

[更新2]
在 System.Data.SqlClient 版本 4.4.0 中,默认是完全托管的。

【讨论】:

  • “在运行时使用”是什么意思?我应该尝试从指定文件加载程序集吗?一定会尝试的。 System.Data.SqlClient.dll 已经在应用程序文件夹中。还可以构建一个带有基本 CRUD 操作的 REST Web API,或者切换到在 .NET Core 上运行良好的 SQLite:/
  • 在运行前用unix目录中的那个复制System.Data.SqlClient.dll
  • 甜蜜!大声笑但是,你没有从我这里听到... ;-) 尽管我为 Microsoft 工作,但这仍然不受支持(目前)。
  • 我今天遇到了同样的问题。添加 UNIX 运行时解决了它。你能解释为什么会这样吗? “完全托管的实施”是什么意思?
  • 本机库(如 sni.dll)特定于处理器(如 x86)。托管库可以在任何处理器上运行。没有适用于 ARM 的 sni.dll 版本,但 System.Data.SqClient.dll 的完全托管版本不使用任何原生库,如 sni.dll。
猜你喜欢
  • 2019-07-21
  • 1970-01-01
  • 1970-01-01
  • 2020-01-29
  • 2020-10-27
  • 1970-01-01
  • 2019-06-28
  • 2019-02-10
  • 1970-01-01
相关资源
最近更新 更多