Add schema to each query in Entity Framework 6 - entity-framework

Firstly, I am new to EF but am an experienced NHibernate user...
I am trying to update an existing EF repository layer that is talking to an existing database to automatically include a schema in every query submitted to the the database. To clarify:
The database tables already exist, but they have been moved to a new schema in SQL Server
The C# class model already exists
The database isn't created each time as is already exists, so the OnModelCreating method of the DbContext is never called. The classes have [Key] etc. from the DataAnnotations namespace, so I'm guessing it's code first.
In NHibernate, this is easy as I can add a default schema when building the configuration, so that every query automatically has the schema added to it regardless of the existing class model - the database and class model don't need to be updated.
Is this possible in Entity Framework and if so, where would I put this override? If not, how can I change EF to inject a schema to each query? Can I override the query generation function?
Thanks

In your DbContext add the following
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("myNewSchema");
}
if there is no schema defined elsewhere this will take care of it globally. I think that an explicitly defined schema elsewhere will override the default schema you set here.

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?

can we use Existing Entities for Entity Framework rather than EF generated Entities

Can i use Entities that are already a part of my project as Entity Framework Entities.
My project Follows Domain Driven Design that do contain all entities that represents my database tables.
I do not want Entity Framework to generate new entities from my existing database, rather i want it to use existing entities in my project.
when ever i use my existing Entities in DB Context Class like this:
public DbSet<SomeOtherProjectInSoulution.ChequeBookRequestAuditLog> ChequeBookRequestAuditLogs { get; set; }
public DbSet<SomeOtherProjectInSoulution.OfflinePayOrderRequestAuditLogEntity> OfflinePayOrderRequestAuditLogEntities { get; set; }
public DbSet<SomeOtherProjectInSoulution.FundsTransferAuditLogEntity> FundsTransferAuditLogEntities { get; set; }
it Gives me the following Error:
The entity type FundsTransferAuditLogEntity is not part of the model for the current
context.
Even though these entities are EXACT Replica of entities that were created by Entity Framework but i deleted them
DB Context:
public partial class PRISMEntitiesTest : DbContext
{
public PRISMEntitiesTest()
: base("name=PRISMEntitiesTest")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<Application.Domain.AuditLog.ChequeBookRequestAuditLog> ChequeBookRequestAuditLogs { get; set; }
public DbSet<Application.Domain.AuditLog.OfflinePayOrderRequestAuditLogEntity> OfflinePayOrderRequestAuditLogEntities { get; set; }
public DbSet<Application.Domain.AuditLog.FundsTransferAuditLogEntity> FundsTransferAuditLogEntities { get; set; }
}
The problem is that, when you make a change in the model, the entity (the class) changes, and the EF model doesn't match with the DB. The first time a DbContext is initialized in an application it checks if the EF model matches the DB. If you update the model, and don't update the DB you'll get an exception.
One alternative is marianoc84 answer: drop and create the DB on all iterations, but I must propose a cleaner solution:
forget the model that you have in the designer view
use pure EF Code First, i.e. define the model using code, not a diagram
use Migrations
You can do the task 1 by deleting it. Yep, delete the model. You're using DDD, you don't need that
For the step 2, you can use something like "EF Reverse POCO Code First Generator". This will allow you to create one or several Code First models from your DB (i.e. create pure POCO classes, and the Code First configuration for them, like column types and sizes, keys, relations...). When you get used to this way of working, you'll see that it matches DDD in a better way, because, instead of modifying a diagram, you'll directly modify an entity (class) and can move that changes to the DB (that's the step 3)
Setp 3: If you use marianoc84 solution, and have only one DbContext, you don't need to take this step. If you have several context,or don't want to drop and create the DB whenever you start your app, then you can use Migrations. With Migrations you can evolve the Code First model and apply the changes to the DB in a non-destructive way. Basically you make to enable migrations and create an "Initial Migration" in the initial moment when the DbContext and the DB schemas match in their original state. You'll see a file created in a "Migrations" folder in your project. From this point on, you can change the classes in your DbContext, and create new Migrations. Each migration have "instructions" on how to modify the DB schema from the previous migration to the recently created (Up) and vice versa (Down), and you have to give it a name. When you want to update the database, you simply have to do run an Update-Database command, which, by default, will update your DB to match the last migration.
In fact Migrations are much more powerful: they allow to move up and donw from migration to migration, apply the changes directly in the DB, be suctomized, generate a SQL Script to update the DB... Google for EF Migrations and you'll find a lot of examples on how you use it. But perhaps this is the best information available.
NOTE: the new EF release which is being developed, and will be probably named "Entity Framework 7", won't have the option to define the DB as a diagram: it will be compulsory to use Code First, and there are good reasons for it. You can get plenty of info about this in the ADO.NET blog.
Try adding this constructor, to your class:
public PRISMEntitiesTest(string nameOrConnectionString)
: this(nameOrConnectionString, new DropCreateDatabaseIfModelChanges<PRISMEntitiesTest>()) { }
DropCreateDatabaseIfModelChanges is an implementation of IDatabaseInitializer that will DELETE, recreate, and optionally re-seed the database only if the model has changed since the database was created.
This is usefull in coding phase, since you can ignore schema issues.

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

Entity Framework database-first and automatically setting concurrency token for all tables

I am using the entity framework (EF 4.5 using the POCO template that uses the DbContext) and I have a very large model.
Every table in the model has an integer column (named RowVersion). I want to set this column as the concurrency column automatically.
I do not want to manually do this for every table in the EDMX file. And going forward for maintenance I do not want to have to remember to do this.
I was hoping there was something I could add to the context to do this automatically for all tables for me.
I seen this piece of code on another post
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<myEntity>().Property(x => x.RowVersion).IsConcurrencyToken();
}
But this appears to only be for code-first, as the event never gets fired for my model.
Any ideas how I could do this?

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>();
}