在RPi 3(控制台应用程序)上运行的Windows IoT上的Entity Framework Core [英] Entity Framework Core on Windows IoT running on a RPi 3 (Console Application)

查看:92
本文介绍了在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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆