Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EF 6.5 release checklist #2237

Open
3 of 5 tasks
AndriySvyryd opened this issue Apr 3, 2024 · 29 comments
Open
3 of 5 tasks

EF 6.5 release checklist #2237

AndriySvyryd opened this issue Apr 3, 2024 · 29 comments
Assignees
Milestone

Comments

@AndriySvyryd
Copy link
Member

AndriySvyryd commented Apr 3, 2024

@AndriySvyryd AndriySvyryd added this to the 6.5 milestone Apr 3, 2024
@AndriySvyryd AndriySvyryd self-assigned this Apr 3, 2024
@ErikEJ
Copy link
Contributor

ErikEJ commented Apr 4, 2024

Whoa!!

Are you planning any preview releases? 🙏

@AndriySvyryd
Copy link
Member Author

Yes, but we haven't decided on how many there will be.

@AndriySvyryd
Copy link
Member Author

We've just released a preview version of Microsoft.EntityFramework.SqlServer 6.5.0. Please try it and let us know if you run into any issues.

@ErikEJ
Copy link
Contributor

ErikEJ commented Apr 18, 2024

@AndriySvyryd Amazing news, Andriy !

@Bartleby2718
Copy link

Great news for sure, but @AndriySvyryd what's the reason behind the release? Is it for Microsoft.Data.SqlClient support?

@ErikEJ
Copy link
Contributor

ErikEJ commented Apr 20, 2024

@Bartleby2718 Yes, and some small Dependency and tooling updates

@chandlerkent
Copy link

@AndriySvyryd just wanted to let you know we've migrated from ErikEJ.EntityFramework.SqlServer to Microsoft.EntityFramework.SqlServer@6.5.0-preview2-24180-01 and have been running it in our test environments without issue.

Is there an ETA at getting a released version?

Thanks!

@AndriySvyryd
Copy link
Member Author

@chandlerkent We plan to release the final version next month. It will likely be identical to 6.5.0-preview2

@jons-bakerhill
Copy link

Not sure if it's the switch to Microsoft.Data.SqlClient or the switch to the new provider but in my local test migration I'm seeing queries timeout because of transactions that didn't timeout previously. I'm honestly not sure how the code as written worked in the past so something is probably behaving more correctly now but I'm not sure what.

Roughly speaking (it's legacy code, not how we do it now) we have 2 DbContext instances. One is used for the data modification and the other is used for pre/post object retrieval for auditing changes. When the modification context is used in a transaction and the query to get the modified object is in the transaction block (but not part of it because it's a different connection) for comparison times out because the transaction is still open.

As I typed out the above maybe previously the connection got reused more or cleaned up less and somehow the "audit" context snuck into the transaction? A pretty wild guess though, seems unlikely.

@ErikEJ
Copy link
Contributor

ErikEJ commented May 16, 2024

@jons-bakerhill You post seems quite off topic here, but have you tried using 5.2.0, which has this fix? dotnet/SqlClient#2301

@jons-bakerhill
Copy link

Somewhere along the way I was thinking of this as a "please try this and provide feedback" issue and lost the "checklist" part of it in my head.

It's not the issue you linked though. The exceptions I'm getting are definitely code misbehaving and trying to query data that is changed in a transaction where the connection doing the query isn't part of that transaction. I'm a bit puzzled how it ever worked and thought I'd ask/note that it seems like either the new provider or the new version of EF itself seems to be "more correct" now. It could be something else entirely.

@ErikEJ
Copy link
Contributor

ErikEJ commented May 16, 2024

@jons-bakerhill No problem, I prefer to get these reports now. Maybe it is a "bad behaviour" that has been fixed now, is that what you are saying?

If you can provide a simple console app repro I can take a quick look, otherwise

@jons-bakerhill
Copy link

Maybe it is a "bad behaviour" that has been fixed now, is that what you are saying?

Yes.

It will likely be a few business days (at best) for me to have time to set up a console app reproduction but I'll try to find some time to do so.

@jons-bakerhill
Copy link

It looks like our command interceptors weren't getting added anymore (they set the transaction to READ UNCOMMITTED, so the transaction lock is ignored).

We relied on having a class derived from DbConfiguration public class RegisterInterceptors : DbConfiguration in the same assembly to register them and after adding/switching to using the DbConfigurationType(typeof(MicrosoftSqlDbConfiguration))] attribute on the DbContext it no longer is called. Maybe something for the readme on the NuGet package for Microsoft.EntityFramework.SqlServer https://www.nuget.org/packages/Microsoft.EntityFramework.SqlServer/#readme-body-tab

I've updated our code to add the interceptors in the API service startup code and removed the derived class. Things appear to be working fine again.

@ErikEJ
Copy link
Contributor

ErikEJ commented May 20, 2024

@jons-bakerhill some sample code with your fix would be very helpful if you think this is a candidate for readme inclusion

@ErikEJ
Copy link
Contributor

ErikEJ commented May 20, 2024

So did you have code like this?

public class FE6CodeConfig : DbConfiguration
{
public FE6CodeConfig()
{
this.AddInterceptor(new EFCommandInterceptor());
}
}

And did you try to change to:

public class FE6CodeConfig : MicrosoftSqlDbConfiguration { public FE6CodeConfig() { this.AddInterceptor(new EFCommandInterceptor()); } }

@jons-bakerhill
Copy link

jons-bakerhill commented May 20, 2024

I believe adding [DbConfigurationType(typeof(MicrosoftSqlDbConfiguration))] to the DbContext broke the automatic registration of the interceptors via deriving from DbConfiguration

[DbConfigurationType(typeof(MicrosoftSqlDbConfiguration))]
public class DerivedDBContext : DbContext

So I replaced

using System.Data.Entity;

namespace Project.Interceptors
{
    public class RegisterInterceptors : DbConfiguration
    {
        public RegisterInterceptors()
        {
            AddInterceptor(new SetSecuritySessionContext());
            AddInterceptor(new IsUserActiveInterceptor());
            AddInterceptor(new SetSecuritySessionSysDbContext());
        }
    }
}

with DbInterception.Add calls in Startup.cs

[assembly: OwinStartup(typeof(OrgNamespace.Startup))]
namespace ApiNamespace
{
    public partial class Startup
    {
        public static void Configuration(IAppBuilder app)
        {
            // Removed boiler plate code

            DbInterception.Add(new SetSecuritySessionContext());
            DbInterception.Add(new IsUserActiveInterceptor());
            DbInterception.Add(new SetSecuritySessionSysDbContext());

        }
    }
}

@ErikEJ
Copy link
Contributor

ErikEJ commented May 20, 2024

Thanks, but did you try deriving from MicrosoftSqlDbConfiguration ?

@jons-bakerhill
Copy link

Thanks, but did you try deriving from MicrosoftSqlDbConfiguration ?

I just tried again with the code below after commenting out my startup additions and it was never called.

using System.Data.Entity.SqlServer;

namespace OrgNamespace.Interceptors
{
    public class RegisterInterceptors : MicrosoftSqlDbConfiguration
    {
        public RegisterInterceptors()
        {
            AddInterceptor(new Interceptor1());
            AddInterceptor(new Interceptor2());
            AddInterceptor(new Interceptor3());
        }
    }
}

image

@ErikEJ
Copy link
Contributor

ErikEJ commented May 20, 2024

Since you already have a derived DbConfiguration class, I believe you should do like this (as documented, but maybe the wording could be inproved)

Or you can add the following lines to your existing DbConfiguration class:

SetProviderFactory(MicrosoftSqlProviderServices.ProviderInvariantName, Microsoft.Data.SqlClient.SqlClientFactory.Instance);
SetProviderServices(MicrosoftSqlProviderServices.ProviderInvariantName, MicrosoftSqlProviderServices.Instance);
// Optional
SetExecutionStrategy(MicrosoftSqlProviderServices.ProviderInvariantName, () => new MicrosoftSqlAzureExecutionStrategy());

@jons-bakerhill
Copy link

jons-bakerhill commented May 20, 2024

I believe you should do like this

Did something get lost from the first half of your previous comment?

Or you can add the following lines to your existing DbConfiguration class:

I'm not sure how adding lines to the derived RegisterInterceptors class would help since it's not getting called in the first place.

It took a bit to click but I think what I need to do if I want to use the attribute to point the context to the new Microsoft.Data provider is to point directly to my derived class instead of the base class. That is [DbConfigurationType(typeof(RegisterInterceptors))] instead of [DbConfigurationType(typeof(MicrosoftSqlDbConfiguration))] which seems to be working in my testing so far.

@ErikEJ
Copy link
Contributor

ErikEJ commented May 20, 2024

I'm not sure how adding lines to the derived RegisterInterceptors class would help since it's not getting called in the first place.

You should not use the attribute in this case. Notice the Or conditions in the readme.

@ErikEJ
Copy link
Contributor

ErikEJ commented May 20, 2024

MicrosoftSqlDbConfiguration is not a base class, it is just a convenince helpers.

@jons-bakerhill
Copy link

jons-bakerhill commented May 20, 2024

MicrosoftSqlDbConfiguration is not a base class, it is just a convenince helpers.

Inheriting from it (public class RegisterInterceptors : MicrosoftSqlDbConfiguration) instead of DbConfiguration and using the derived class in the DbConfigurationType attribute seems to work fine. How is that not using it as a base class?

My suggestion (based on what I think is finally a mostly complete understanding) would be to add a note along the lines of "If you are using a customized DbConfiguration by deriving from it in the same assembly as your DbContext you need to call DbConfiguration.SetConfiguration or apply the DbConfigurationType attribute. Make sure to use your custom class in the call or attribute and make sure it is based on MicrosoftSqlDbConfiguration"

I have a couple options at this point, I just want to keep the configuration out of web.config to ease the migration to .Net 6+. It's just a matter of deciding which one will work best in our solution.

Thank you for working through this with me, it's much appreciated!

@ErikEJ
Copy link
Contributor

ErikEJ commented May 20, 2024

I think this clarification is enough, but I will test it:

Or add the following lines to your existing derived DbConfiguration class:

@jons-bakerhill
Copy link

jons-bakerhill commented May 20, 2024

I think this clarification is enough, but I will test it:

Or add the following lines to your existing derived DbConfiguration class:

Oh... your prior comment #2237 (comment) makes more sense now. Without quotes or a link it wasn't clear to me that was a full quote from the readme page. I'm a little slow on the uptake today it appears, must be because it's a Monday :D

AndriySvyryd pushed a commit that referenced this issue May 21, 2024
@3nth
Copy link

3nth commented May 21, 2024

Not sure if this is the readme to note this, but if you are using EF6.5 on .NET Core with Microsoft.SqlServer.Types (DbGeography) then you are limited to deploying to windows and you must package with a windows runtime identifier and --self-contained true or the DbGeography won't load.

For Azure Web Apps at least. Not sure if it's an issue for an IIS deployment.

@ErikEJ
Copy link
Contributor

ErikEJ commented May 21, 2024

@3nth Please share a simple console app that demonstrates this issue, and I will have a closer look.

ErikEJ added a commit to ErikEJ/EntityFramework.Docs that referenced this issue May 22, 2024
AndriySvyryd pushed a commit to dotnet/EntityFramework.Docs that referenced this issue May 22, 2024
@3nth
Copy link

3nth commented May 22, 2024

@ErikEJ This is looking like a peculiarity with Azure App Services.

Runtime identifier does appear to be required due to the windows only libraries in Microsoft.SqlServer.Types.

With regards to --self-contained I've found that the net6 MVC app deployed to Azure App Services does require --self-contained true. With false get this error when DbGeography.Distance() is used.

Message: Specified type is not registered on the target server. Microsoft.SqlServer.Types.SqlGeography, Microsoft.SqlServer.Types, Version=16.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91.
Microsoft.Data.SqlClient.SqlCommand+<>c.<ExecuteDbDataReaderAsync>b__211_0(Task`1 result):8

A peculiarity is we also have a net6 console app that gets run in the background via WebJobs and it crashes at start unless --self-contained false is used. This one is hosted on Azure App Services as well, but the web app itself is .NET Framework MVC (last one to migrate). I don't think this is related to anything here, the console app itself runs just fine on the host via remote shell, so something with WebJobs hosting more likely.

None of this has been reproduceable locally. Cannot make sense of it, but we have a working deployment now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants