0

I've tried to come up with a better title but can't.

The issue is I am new to Azure functions but have made a simple one work that writes to a SQL Azure table. Now I've attempted to build the simplest kind of Entity Framework based Datalayer and uploaded it. Right now it is compiled as .Net 4.6 and using EF 6.1.3.

I'm using a connection string as per the second answer here Second answer and have checked it is being retrieved correctly. Update - I also used this guide.

Removing this {#r "D:\home\site\wwwroot\sharedbin\TestDataLayer.dll"} causes the editor to complain about missing assemblies, so it IS finding the dll in question.

However it will not run - it cannot find TestDataLayer.dll.

I'm only running this in the portal editor (I've not yet mastered deployment direct from a Visual Studio Project - don't laugh :P).

#r "System.Configuration"
#r "System.Data.Entity"
#r "D:\home\site\wwwroot\sharedbin\TestDataLayer.dll"

using System;
using System.Collections;
using System.Configuration;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.Entity.SqlServer;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.Net;
using TestDataLayer;

public static void Run(TimerInfo myTimer, TraceWriter log)
    {
       var connection =  ConfigurationManager.ConnectionStrings["sql_connection"].ConnectionString; 
       using(var db = new SyncDbContext(connection))
            {
                var RK = new RKAzureTest()  {TestField1 = "It finally worked?" };
                db.RKAzureTests.Add(RK);
                db.SaveChanges();
            }
    }       

[DbConfigurationType(typeof(myDBContextConfig))] 
public partial class SyncDbContext : System.Data.Entity.DbContext
{
    public SyncDbContext(string cs) : base(cs) {}
    public DbSet<RKAzureTest> RKAzureTests {get;set;}

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
 //       modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }

}

    public  class myDBContextConfig : DbConfiguration
        {
            public myDBContextConfig()
            {
                SetProviderServices("System.Data.EntityClient", 
                System.Data.Entity.SqlServer.SqlProviderServices.Instance);
                SetDefaultConnectionFactory(new System.Data.Entity.Infrastructure.SqlConnectionFactory());
            }
        }

This is the function.json:

   {

    "frameworks": {

        "net46":{
                    "dependencies": {

                        "EntityFramework": "6.1.3"
                    }
                }
    }

}

I've compiled the dll itself to .Net 4.6 after a suspicion that the Azure Functions don't support .net 4.7.1 and via Kudu uploaded the compiled dll to a sharedbin folder (checked the path a dozen times!).

This is the error thrown up:

    2018-05-01T11:00:00.012 [Warning] Unable to find assembly 'TestDataLayer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Are you missing a private assembly file?
2018-05-01T11:00:00.012 [Error] Exception while executing function: Functions.TimerTriggerCSharp1. mscorlib: Exception has been thrown by the target of an invocation. f-TimerTriggerCSharp1__514732255: Could not load file or assembly 'TestDataLayer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

Not quite sure what else can be left - I'm using runtime version 1.0.11702 in the Application settings as I found life got a LOT more complicated if I went onto the Beta version.

If anyone can point me to a working guide for this use case (Database first, EF 6.1.3 etc) I'd be grateful.

Any help offered gratefully received!

Thank you :)

Richard Griffiths
  • 758
  • 1
  • 11
  • 23
  • the path to your assembly should be "D:\home\site\wwwroot\bin\TestDataLayer.dll" as far as I think. Since you have 3rd party dll dependencies,you should build functions using vs2017 and then publish them. This way the dependencies are managed properly, and it uses a .cs file instead of .csx – inthevortex May 01 '18 at 12:11
  • Yeah I haven't mastered how to make publishing from VS work at all tbh. I tried that with an earlier function and well, it didn't go well! However, since I've written to a database using a non EF solution, I know this should work. I do know removing my /r path causes even compilation to fail - however have tried the alternate path after uploading the dll correctly and restarting the function. Same result. Will research your claim about VS - hope it's not true though as that was hassle (it published, couldn't find the files on the portal?!) – Richard Griffiths May 01 '18 at 12:21
  • try the kudu console to look for your dll, and determine it's absolute path in azure. – inthevortex May 01 '18 at 12:24
  • Oh I've done that - got Kudu open now with the powershell prompt. It's definitely the right path. Kudu is how I'm uploading the DLL each time I try something else. I can't believe that the only way one can use a 3rd party (well, my own dll) is to publish via VS mind. None of the sources I've tried mention this. On the other hand this is frustrating as an experience - I don't quite see how I can compile yet it moans it can't find it. It's there LOL. – Richard Griffiths May 01 '18 at 12:30
  • I've tried publishing from VS - not really having much luck. I do keep hoping I'll see someone with a full step by step blog post on making EF 6.1.3/6.2 work on Azure functions as so far, I'm getting adept at manouvring round the portal etc but no joy at making the library work. – Richard Griffiths May 01 '18 at 13:42
  • Are all of TestDataLayer.dll's dependencies, and their dependencies (and so on) also present in your sharedbin folder? – Katy Shimizu May 01 '18 at 17:54
  • @RichardGriffiths It'd better to show what are the dependencies of `TestDataLayer` library. – kamil-mrzyglod May 02 '18 at 06:25
  • It's only dependencies were EntityFramework itself and I did add these files just in case. I've had to quit on it for now but I'll have to try again in the next couple of months. It's odd that it's so tricky to get going: tried doing a separate function from Visual studio, so starting again, no joy. After a day and a half, my own conclusion is it does not actually work or work at all easily yet. Fingers crossed it'll be made far simpler in the future :). Anyway, thank you for commenting & trying to help! I'll keep my eyes open for a new guide/updates to Azure functions! – Richard Griffiths May 02 '18 at 10:47
  • Does your build log for TestDatalibrary show any binding redirects being done? These redirects won't be done in a Functions app in the portal, which could break things. – Katy Shimizu May 02 '18 at 22:23
  • I'll investigate later this morning and come back to you, thank you. – Richard Griffiths May 03 '18 at 08:58

1 Answers1

2

Go to Azure Portal, create a folder called, 'bin' inside your Azure functions using CMD Shell, upload the 'TestDataLayer.dll' file to bin folder which has just been created.

#r "System.Configuration"
#r "System.Data.Entity"
#r "TestDataLayer.dll"

Project structure should look like,

AzureFunctionProjectName001
    bin
       TestDataLayer.dll
    run.csx
    project.json
    project.lock.json
    ...

Azure functions should be able to discover your library this time. I believe, EntityFramework works just fine.

Ashokan Sivapragasam
  • 2,033
  • 2
  • 18
  • 39
  • I tried every variation of paths and references - except this one. Other than getting the metadata sorted, this was my answer. Note to others, don't leave tests in that refer to any other connection strings in the DLL. – Richard Griffiths May 03 '18 at 13:37