I am still in the process of porting my old MVC project to the latest asp.net 5 MVC and EntityFramework 7. To accomplish this I first reverse engineered an existing database from the old project using the ef commands. That created all of my model classes correctly (or mostly so). I have manually edited the code to get through all of the initial errors. I have that compiling with almost no additional code from the original project. In other words I only have the model classes, and the DbContext class so far in the solution. All of this is in an assembly and I have no migrations at all in the codebase, just the Migrations directory. What I thought would make sense is to add a migration to baseline the database from what was reverse engineered. I should mention that my DbContext inherits from IdentityDbContext
public partial class STOrmContext : IdentityDbContext<ApplicationUser>
{
}
My project is split into two components. All database and models in an assembly, and MVC stuff in a separate project.
when I type
dnx ef command migrations add Initial
I get the following error message
The entity type 'Microsoft.AspNet.Identity.EntityFramework.IdentityUserLogin<string>' requires a key to be defined.
I guess I just don't really understand how to bootstrap a legacy database into EntintyFramework 7. Can someone point me in the right direction.
I found the answer myself.
It turns out it was a couple of things I was not addressing.
When I reverse engineered the old database it created models for the
identity stuff from the legacy application.
I deleted those.
I also needed to call the base OnModelCreating() so that it could configure
Identity stuff.
protected override void OnModelCreating(ModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
}
I guess I should have paid more attention to what was really happening before jumping to a question on StackOverflow
Related
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?
I would like to use a Database First approach to managing my database with EF Core, and not just for the initial database creation. I'm using this command to generate my entity models and mapping code:
Scaffold-DbContext "Server=(localdb)\mssqllocaldb;Database=MyDB;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models/Entities -f
Now this works fine. I'm just struggling with identity integration. Currently I have two separate contexts, the one generated by the scaffolding command and an identity context that looks like this:
public class IdentityContext : IdentityDbContext<ApplicationUser> {
public IdentityContext(DbContextOptions<IdentityContext> options)
: base(options) {
}
protected override void OnModelCreating(ModelBuilder builder) {
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
}
Both contexts read from the same database and are registered like this:
services.AddDbContext<ApplicationContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext<IdentityContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
Is it reasonable to have two separate contexts? Will it cause future problems as I start creating relationships between users and other models? I couldn't find anything in the docs regarding continued use of db-scaffold to generate my entity models and mappings.
Let me know if I can clarify anything.
ORIGINAL CONTEXT
Okay so clearly my original question wasn't any good.
I'd just like some clarification on if my Database First workflow with .NET Core and Entity Framework is the right way. I've read all the articles I can find about using Database First, which all seem to end with: "now you have scaffolded your database so can start using Code First migrations". I want to continue writing my SQL and just keep mapping it to entities.
To manage and update my application I'm using the excellent DbUp project. So I write my scripts, apply them to the database
This appears to be working fine so far. My only problem is integrating identity nicely. Currently I just have two contexts, my application one and an identity one. My application one has also mapped all the identity tables. It is working fine but I'm not sure what will happen going forward as I start linking tables to the user... I believe I did make it work with one context but I had to modify the generated application context each time, removing all the Identity mappings and inheriting from IdentityDbContext (to generate the identity mappings). I could change the schema of the identity tables/my tables and just generate the mappings for my tables, excluding the identity tables. Then I will probably need to manually write mapping properties on ApplicationUser, is that correct?
Basically, I'm not really feeling like Database First is a first class citizen in .NET anymore. Am I just missing something obvious to have this kind of just "work" without modifying generated code? Or am I overthinking this and just need to get on with it?
Apologies for the rambling, one of those days I guess.
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
I've been using Entity Framework Code First migrations for a while now, and like to think I know the fundamentals pretty well. However, yesterday I came across a rather odd issue which I can't seem to find a solution to.
I've added a reference to a DLL (third party - not developed by ourselves) which has some interfaces I need on my entities. The DLL contains a bunch of other things - such as some classes - which we don't need and aren't using.
Now with the reference, and implementing some of the interfaces - when I add a migration using the Add-Migration command, Entity Framework seems to pick up some of the classes in the DLL, and tries to create tables for them in the migration.
For example, I have a 'User' entity in my project. I have added a reference to ThirdParty.dll, which contains an IThirdPartyUser interface. The DLL also contains a UnusedClass, which I am not using - it is not part of my context in any way.
When I create a migration, I get code to create the database tables for UnusedClass. For example:
CreateTable(
"dbo.UnusedClass",
c => new
{
Id = c.Int(nullable: false, identity: true),
RegistrationNumber = c.Int(),
})
Now my theory is that this external assembly (incorrectly) has some dependency on Entity Framework - but I can't figure out why migrations is trying to generate database code for them - especially as they are not part of my context.
Anyone come across this before? I'm about to embark on a trial and error exercise to try and get to the bottom of the issue.
EF should only pick up classes that are in the object graph originating at your DbContext - so, if class A is in your context, and class A has a property of type UnusedClass, EF will try to scaffold it.
You can add the NotMappedAttribute to a property or class to have EF ignore it when generating its mapping.
I am currently using the Entity Framework Powertools (beta 4) to generate my POCO classes from an existing db, which has upwards of 800 tables.
Whilst this is awesome, and saving me a lot of time, I noticed that the tool is pluralizing my POCO classes, or de-pluralizing them. Some of our tables are pluralized, and others are not, so to keep things simple, I want the POCO's to match the underlying db table names. In my main DbContext, I have the PluralizingTableNameConvention and PluralizingEntitySetNameConvention removed in the OnModelCreating() method call, so the application is fine.
My question is whether this configuration can be re-created in the EF Powertools so that the classes come out correctly, and do not require me retrofitting the class names etc.
It looks like this cant be done, however I have download the EF Powertools code from Codeplex, and built the tools manually. I then created my own implementation of the PluralizationService in which I did not pluralize anything.
Job done.