在RPi 3(控制台应用程序)上运行的Windows IoT上的Entity Framework Core

编程入门 行业动态 更新时间:2024-10-22 13:42:41
本文介绍了在RPi 3(控制台应用程序)上运行的Windows IoT上的Entity Framework Core的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我成功地将.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库)并覆盖应用程序文件夹中的现有文件夹即可解决此问题.请参阅下面的答案.

解决方案

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

我希望我能告诉您如何使用System.Data.SqlClient的完全托管实现(在Linux上使用的实现),但是很遗憾,它使用了System.Threading.Thread,这在UWP上不可用...

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

[Update2] 在System.Data.SqlClient版本4.4.0中,它看起来像是默认情况下完全受管理的.

I successfully deployed a .NET Core Console Application to my Windows IoT running on a Raspberry Pi 3.

The application pulls data from a webservice and stores them in a database. I used Entity Framework Core for that.

When I start the deployed console application (.exe) through the remote powershell everything works except the access to my database running on Azure. When the application tries to read from the database it throws the following exception:

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)

There is no 'sni.dll' in the application folder.

Deployed the application using the 'win8-arm' runtime.

  • netcoreapp2.0
  • .NET Core 2.0 SDK (Runtime and tooling)

Any ideas what's wrong?

Update:

Copying the System.Data.SqlClient.dll (unix lib) and overriding the existent one in the application folder solved the issue. See answer below.

解决方案

There is no native sni.dll library for ARM. (See dotnet/corefx#9064)

I was hoping I could tell you how to use the fully-managed implementation of System.Data.SqlClient (the one that's used on Linux), but it unfortunately uses System.Threading.Thread which isn't available on UWP...

[Update1] Wait, you're not using UWP. :) Try getting the app to use %USERPROFILE%.nuget\packages\system.data.sqlclient\4.3.0\runtimes\unix\lib\netstandard1.3\System.Data.SqlClient.dll at runtime.

[Update2] It looks like in System.Data.SqlClient version 4.4.0, it will be fully-managed by default.

更多推荐

在RPi 3(控制台应用程序)上运行的Windows IoT上的Entity Framework Core

本文发布于:2023-11-15 03:48:40,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1590871.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:控制台   应用程序   Windows   RPi   Framework

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!