dotnet / EntityFramework.Docs

Documentation for Entity Framework Core and Entity Framework 6
https://docs.microsoft.com/ef/
Creative Commons Attribution 4.0 International
1.63k stars 1.96k forks source link

Azure Function documentation badly needed #926

Open jrichview opened 6 years ago

jrichview commented 6 years ago

I just developed my first Azure Function. I've been a professional software dev since the 1980s and I really struggled to find the information I needed to make Entity Framework Database First work with an Azure Function. It so happened I put it in a .NET class library because I needed to reuse that code. But making the connection work took me several days of experimenting with google results until I stumbled on the correct thing.


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

jrichview commented 6 years ago

And that was just to get it working locally. Learning what to do to deploy it was another effort and I'm not sure whether the solution I ended up with would be considered a best practice or not.

Levifox9 commented 6 years ago

What was your work around ?

jrichview commented 6 years ago

For running locally, I'd like to give credit to this video: https://www.youtube.com/watch?v=RMBE7cWDUbM

For deploying live, I used a combination of ideas from StackOverflow: https://www.youtube.com/watch?v=RMBE7cWDUbM

It's important to understand a few things for starters:

1) Developing an Azure function in the portal generates quite a different project than developing an Azure function in Visual Studio (I was doing the latter).

2) You can't really use EF, at least not database first, from an Azure Function directly. It's best to put it in a class library, and the type of class library needs to be .NET Framework (Or possibly Core, I have not tried that yet as I have no need to be cross platform at the moment).

3) Understand the difference in EF connection strings for database first vs. code first.

Levifox9 commented 6 years ago

Thanks for you quick reply! The problem i have is, that i run it already locally with EF in a class library. I published the function to azure. But now the function does not use the connection string for my Azure SQL DB for the context. How did you manage that? I read so much, but nothing seems to work.

jrichview commented 6 years ago

Sorry, just realized my paste of the StackOverflow link was bad. Rather than hunt it down again, I'll try to explain briefly.

I modified my Database Context's template (.tt file) to output two constructors. The default one uses the connection string just as it would normally look. The static constructor checks for a setting that only exists in the live environment where I deploy the Azure Function. If it finds that, it explicitly retrieves the connection string:

public partial class SampleEntities : DbContext { private static string _connectionString = "name=SampleEntities";

    // if running as deployed Azure Function handle lack of provider type
    static SampleEntities()
    {
        // check for a setting that flags we're running as deployed Azure Function 
        if (!string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("LiveEnvironment")))
        {
            string conn = System.Environment.GetEnvironmentVariable("SampleEntities");
            if (!string.IsNullOrEmpty(conn))
                _connectionString = conn;
        }
    }

    public SampleEntities()
        : base(_connectionString)  // this is like the default template constructor except uses a variable
    {
    }

As I said, I got this idea from a StackOverflow post. Sorry I pasted the wrong link, but it's out there if you google. I realize there is a ton of information/misinformation about how to achieve this out there.

jrichview commented 6 years ago

The idea is when you are running within the published function you specify the connection string itself rather than the name of it. You could hard-code it in there if you prefer.

neil-rubens commented 5 years ago

I ended up using System.Environment.GetEnvironmentVariable since it seems to be the recommended way according to

The System.Configuration.ConfigurationManager.AppSettings property is an alternative API for getting app setting values, but we recommend that you use GetEnvironmentVariable as shown here. https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-class-library#environment-variables

p.s. adding/editing is handy via VS Publish/Manage Application Settings/ (it retrieves/puts settings for both local and remote values).

Although for EF ConnectionString there seems to be a conflicting recommendation

Recommended way seems to store it under ConnectionStrings section of local.settings.json https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local#local-settings-file https://docs.microsoft.com/en-us/azure/azure-functions/manage-connections#sqlclient-connections However deployment on Azure requires manually entering it via azure portal Function App / Application settings / Connection string; this requires extra effort so is not quite as convenient.

The first approach above; seems more convenient (but probably less correct way) is to store it in Application Settings there are values for local and remote and could be nicely viewed/edited with VS Publish \ Manage Application Settings panel; and retrieved by System.Environment.GetEnvironmentVariable as described above.

p.s. would definitely appreciate a best practices example in the official docs (rather than having to search for it all over the places)

Other Refs

https://blog.jongallant.com/2018/01/azure-function-config/ didn't work for me

https://stackoverflow.com/questions/35120725/ef6-connection-string-in-azure https://stackoverflow.com/questions/36559467/sql-azure-ef-database-first-connection-string-in-azure-management-portal https://stackoverflow.com/questions/18947393/azure-web-sites-connection-string-for-ef-not-being-picked-up/18964294#18964294 https://social.msdn.microsoft.com/forums/azure/en-US/62b9fa9d-7a4a-4927-a702-3e1e834d5187/azure-web-sites-connection-string-for-ef-not-being-picked-up