How to create stored procedure in EF Core using .NET 6 - entity-framework-core

I have a class library project in .NET 6 where I am using EF Core. I am able to create tables using the code-first approach, but stuck on how to create stored procedures. I have seen a few articles on Google but it's showing using old EF 6 but not for EF Core.

There is no automatic way to create a stored procedure with EF Core, but the process to do it manually is quite simple.
First create a new migration as you would normally, it should be empty. Then edit the migration to manually create the procedure. For example:
public partial class MyNewStoredProcMigration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("CREATE PROC DoStuff....");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("DROP PROC DoStuff");
}
}
Note that you may want to move the string for the procedure into a resource file to keep things tidy.

Related

Entity Framework Core - Changing Database Schema at runtime without running migration

I have a .NET Core 5 application with Entity Framework (code first) with migrations and Azure SQL database.
I want to run two separate applications on same DB with different data. I want to have test and demo application. My idea was to change schema for each application. One application will have schema "test." and another one "demo.".
I tried to do this with this article
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("demo");
}
Problem is that I need to run Add-Migration with this approach. And I don't want to do that.
There is also another way that I didn't try. Described here
Problem there is that I need to create EntityConfiguration for each Entity and I don't want to do this neither.
I want to set schema globally for all tables at once.
Is there a way how to do this without creating new migrations? Or is there a better way without changing scheme?

Identity 2.0 CodeFirst Migration to Use Stored Procedures

I'm trying to move my existing ASP.Net Identity Framework project across to use Stored Procedures on the existing models. I have migrations already enabled, and have an existing database which is basically the stock/standard the Identity builds (few extra columns here and there). I have tried to enable the Stored Procedures via the DbContext:
public class IdentityDbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ApplicationUser>().ToTable("Users").MapToStoredProcedures();
modelBuilder.Entity<ApplicationRole>().ToTable("Roles").MapToStoredProcedures();
}
}
Then I generate the migration:
Add-Migration -Name AddStoredProcedures
And apply the migration:
Update-Database
Now when I try to run my application I am getting the exception when it attempts :
System.InvalidOperationException: The model backing the 'IdentityDbContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269)."}
AFAICT, I ran the update correctly (__migrationhistory table contains the name of the migration). Looking at my database, the stored procedures are added. Why does the framework not recognize it?

How to create spatial index using EF 6.1 fluent API

Well, the question is clear enough. Is it possible to create spatial indexes using Entity Framework 6.1 fluent API?
The only way I know to do this is through a "custom" migration. In EF6, I add a migration (in the example below it's named "V1"), resulting in an new migration with empty Up() and Down() methods. You can then add custom SQL commands to these methods before running update-database to put these in the "normal" migrations flow.
It's possible to modify an existing migration to add these features, but I prefer in practice to keep my automatically scaffolded migrations separate from my customized ones.
public partial class V1 : DbMigration
{
public override void Up()
{
Sql("CREATE SPATIAL INDEX [IX_UserProfileAddresses_Location] ON [dbo].[UserProfileAddresses](Location)");
}
public override void Down()
{
Sql("DROP INDEX [IX_UserProfileAddresses_Location] ON [dbo].[UserProfileAddresses]");
}
}
Not an ideal method, but not too bad since it does follow the "normal" migrations pattern for EF.
Short answer- No, it is not. I have seen this tangentially referenced throughout blogs and have found no concrete examples of implementation. It seems to be related to the fact that spatial indexes are filtered indexes, which are not supported in Entity Framework.
As support for my answer I constructed a POC console app with the most recent version of Entity Framework (6.1). I took the following steps
Created a model that had a property of the type DbGeography
Enabled automatic migrations
Ran Update-Database -verbose insuring migration with the addition of an index was run. The index used the following:
modelBuilder.Entity<LocationEntity>().Property(t => t.Coordinates).HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("ix_locationentity_coordinates")));
No indexes were created, but neither did the app crash. I could try permutations on this, but my example seems to follow the convention of entity framework: Official Fluent Documentation

EF: Automatic migrations are running when disabled

I'm trying to update the database on a build server, and it's failing because it's trying to run automatic migrations, even though they're disabled. The database already exists and I just need to apply the latest migration. Here's my context:
public sealed class Configuration : DbMigrationsConfiguration<CableSenseInstanceConfiguratorContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
}
I've got a bunch of migration files I've created manually, here's the latest one:
public partial class Settings : DbMigration
{
public override void Up()
{
AddColumn("dbo.MasterInstances", "Settings", c => c.String());
}
public override void Down()
{
DropColumn("dbo.MasterInstances", "Settings");
}
}
If I then manually update the database from the package manager console, I see it tries to run an automatic migration (which fails because the table already exists):
Applying code-based migrations: [201204200805145_NoMoreCerts, 201210311451543_SuperUsers, 201301041036414_Settings, 201301041128583_Settings2].
Applying code-based migration: 201204200805145_NoMoreCerts.
Applying automatic migration: 201204200805145_NoMoreCerts_AutomaticMigration.
My __MigrationHistory table just has the one entry for the initial creation. How can I stop it from doing the automatic migrations?
Check out the answer from jjslagace here:
Update-Database tries to do an automatic migration even with automatic migrations disabled
You are building your migrations manually. My guess is entity framework wants to add something that you don't have in your migration script, or it wants to name columns differently etc. EF has a brain, and that brain is fairly simple. It's expecting things to be a certain way unless you tell it otherwise using fluent (not by manually creating/tweaking migration files). From the answer on the question above it sounds like sometimes that results in the issue you are seeing.
Long story short don't build the migration files manually. Instead run the add-migrations command. This will create the migration for you and you can see what EF is expecting to do before it's applied to your database (because sometimes it's stupid). If you need to override what EF is generating for you add a fluent mapping in your DBContext class by overriding OnModelCreating. Then just run add-migration again with the -force option. Here is a good reference for using the Fluent API to custimize EF mappings. Rinse and repeat until you get the migration you are looking for then run update-database.
Hope that helps!

Entity framework CTP5 Model compatibility cannot be checked because the database does not contain model metadata

I am trying to test the Entity Framework CTP 5 Code First with an existing table.
I defined the model class and DbContext and ran the application. It created the database and table.
I dropped EdmMetadata table from the database.
Added Trusted_Connection=true;Persist Security Info=True in my connection string.
When I run the application again, it gives me this error.
System.NotSupportedException was unhandled by user code
Message=Model compatibility cannot be checked because the database does not
contain model metadata.
Source=EntityFramework
How can I make this application run without EdmMetadata table?
If you don't want to use EdmMetadata table try to add this into your DbContext derived class:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
}