EF6 and azure worker role : underlying provider fail on open

azure azure-worker-roles c# entity-framework entity-framework-6

Question

EntityFramework 6 and a PaaS architecture are giving me trouble. I have a repository project that uses a DAL project to run some stored procedures imported from EF6. We had been aiming for an IaaS architecture up until recently, but for various reasons, we moved to PaaS. A WCF service has successfully used this repository. This WCF service has been transformed into a Web Role and functions flawlessly. I now handle data and de-queue a service bus using the same repository in the worker role (en-queued by the Web Role). But when I used the repository to invoke a stored procedure for the first time using EF6, I encountered an issue (a Get request)

Schedule worker error with inner exception : A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) The underlying provider failed on Open. 
at System.Data.Entity.Core.EntityClient.EntityConnection.Open()
at System.Data.Entity.Core.Objects.ObjectContext.EnsureConnection()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass45`1.b__43()
at System.Data.Entity.Infrastructure.DbExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteFunction[TElement](String functionName, ExecutionOptions executionOptions, ObjectParameter[] parameters)
at XXX.DBContext.XXXEntities.GetTrades(Nullable`1 id, Nullable`1 entityBuy, Nullable`1 entitySell, Nullable`1 sessionId, Nullable`1 orderBuy, Nullable`1 orderSell)
at XXX.RepositoryServices.MarketPlaceService.GetTradeInstances(Nullable`1 EntityBuy, Nullable`1 EntitySell, Nullable`1 SessionId, Nullable`1 OrderBuyId, Nullable`1 OrderSellId)
at WorkerRole1.WorkerRole.Run()

(XXX and YYY are namespaces, but I am unable to display them due to policy considerations.) On the database (hosted in IaaS), I attempted to add a firewall exception for Azure for IP range 0.0.0.0 to 0.0.0.4. I included a configuration class that descended from DbConfiguration and configured in ctor as follows:

this.SetExecutionStrategy("System.Data.SqlClient", () => SuspendExecutionStrategy
? (IDbExecutionStrategy)new DefaultExecutionStrategy()
:new System.Data.Entity.SqlServer.SqlAzureExecutionStrategy(5,TimeSpan.FromMilliseconds(25)));

When SuspendExecutionStrategy is set to true, EntityFramework and EntityFramework were both present. The appropriate version of SQLServer dlls is copied into the cspkg.

My network is strong as well (with credentials inside). I'm confident in the last statement because I can utilize ADO.NET sql queries in both the Run function for my worker role and the classes that use this repository. I tried it with the most recent EF6 version (6.1), but it doesn't work. It didn't work when I tried to place my worker in the same subnet as the web roles. I attempted to utilize the SQLServer's IP address in the connection string, but it was unsuccessful. For both EF6 and ADO.NET, the same connection string is utilized.

    <add name="XXXEntities" connectionString="metadata=res://*/XXXContext.csdl|res://*/XXXContext.ssdl|res://*/XXXConte xt.msl;provider=System.Data.SqlClient;provider connection string=&quot;data  source=negobdd1.YYY.com;initial catalog=XXX;user id=[User];password= [Password];MultipleActiveResultSets=True;App=EntityFramework&quot;"  providerName="System.Data.EntityClient" />

(I apologize for the excessive red tape, but the client requires it. I attempted to connect from the Azure VM hosting the worker role to the database with a.udl file using the address "negobdd1.YYY.com" and the user and password of the connection string with success. Also, all of the XXX are precisely the same string. I can successfully ping the SQLServer machine as well.

EDIT

the setting is established in this way

    public partial class NegotiationsPlatformEntities : DbContext
    {
        public NegotiationsPlatformEntities()
        : base("name=NegotiationsPlatformEntities")
        {
        }

    // auto-generated methods here

    }

using this implementation

     internal NegotiationsPlatform.DBContext.NegotiationsPlatformEntities db = new NegotiationsPlatform.DBContext.NegotiationsPlatformEntities();

I only specify the name of the connections string as a special argument.

RE-EDIT

following a review of the DbContext. Database.Connection. Datasource I discovered that EF6 does not appear to be addressing the Azure IaaS SQLServer, but rather the local staging database server. I'll look into it and report back.

I would be very grateful for any assistance.

Thanks.

1
1
6/10/2014 4:58:34 PM

Accepted Answer

As it turns out, worker roles handle connection string files differently than web roles do. We have numerous "connectionStrings" + [target] + ".config" files because there are many deployment environments.

We use a.bat file inside the OnStart method of a web role to remove any extra configuration files and rename the needed file to "connectionStrings.config." In a webrole installed on Azure in this manner, only the PaaS configuration file is kept and used. However, it appears that in a working capacity, it functions differently.

When the cleanup ".bat" file is run, all that is left is one config file with the appropriate content, but it is this default config file's content that is used. So I suppose any modifications won't matter because the worker loads the config file before calling the OnStart method. (I haven't attempted to kill the worker process to test if it loads with the sole good file left over from the initial deployment after a reboot.)

So here's my suggestion: don't rely on the ".bat" file used during OnStart and delete all the configuration files in the worker project other from the PaaS ones.

Dean Ward deserves a lot of credit for directing me in the proper direction. In the end, it was "simply" a matter of connection strings.

0
6/11/2014 7:20:59 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow