I have an issue with Code First. I just migrate the project from Model First to Code First and I think that Entity Framework is losing its mind... Here is my class (simplified) :
public class MyClass
{
// Key, other properties...
public bool? MyNullBoolean { get; set; }
public static void Configure(EntityTypeConfiguration<MyClass> myClass)
{
// Other configuration on other properties...
myClass.Property(m => m.MyNullBoolean).IsOptional();
}
}
Here are some additionnal informations for you :
I call the Configure() method in the OnModelCreating() method.
Migrations are enabled and Automatic mode is set to false
In my migration I have MyNullBoolean = c.Boolean(nullable: false), so EF
is acting like this property is required, wich is not as previously
seen.
I target an existing DB (dev) with data inside so I can't perform Migration "for testing purposes"
This is the exact same model as the one from Model First and that last one is working correctly...
Here is what I tried :
Disabling / Enabling EF on the project (deleting Migrations in project and db)
Restarting VS
Targeting another DB (same structure)
Leave the property unconfigured (so EF do the job alone)
I'm out of idea and I found nothing in the Internet. Thanks for your help guys !
I think that EF was corrupted because when I uninstall it, clean the solution, install it, rebuild the solution, it worked.
So there was no problem with db or my model.
Related
I need to map to a view when using EF6 with migrations.
The view pivots 2 other tables to enable a simple summary view of the underlying data, the idea being it allows us to use this in a summary index view.
The issue I have is I am unable create a migration that either deploys the view (ideal goal) or deploys the DB without the view for later manual deployment.
In most attempts, following other SO questions, I end up either deadlocking the Add-Migration and Update-Database commands or generally causing an error that breaks one or the other.
What is the current best way to use EF6 to access views, even if I lose the ability to automatically deploy them with the migrations, and not cause errors with migrations.
Further detail
The Db contains 2 tables Reports and ReportAnswers. The view ReportView combines these two and pivots ReportAnswers to allow some of the rows to become columns in this summary view.
Reports and ReportAnswers were depolied via EF Migrations. The view is currently a script that needs be added to the deployment somehow.
Reports, ReportAnswers & ReportView are accessible from the db Context
public virtual DbSet<ReportAnswer> ReportAnswers { get; set; }
public virtual DbSet<Report> Reports { get; set; }
public virtual DbSet<ReportView> ReportView { get; set; }
I have tried using Add-Migration Name -IgnoreChanges to create a blank migration and then manually adding the view to the Up() and Down() methods but this just deadlocks the migration and update commands, each wanting the other to run first.
I have also tried using modelBuilder.Ignore<ReportView>(); to ignore the type when running the migrations but this proved incredibly error prone, even though it did seem to work at least once.
I just walked around interesting article about using views with EF Core few days ago, but I found also the very same using EF 6.
You may want to use Seed method instead of migration Up and Down methods.
protected override void Seed({DbContextType} context)
{
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
var baseDir = Path.GetDirectoryName(path) + "\\Migrations\\{CreateViewSQLScriptFilename}.sql";
context.Database.ExecuteSqlCommand(File.ReadAllText(baseDir));
}
Your SQL command should look like sample below.
IF NOT EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[{ViewName}]'))
EXEC dbo.sp_executesql #statement = N'CREATE VIEW [dbo].[{ViewName}]
AS
SELECT {SelectCommand}
It is not perfect, but I hope at least helpful.
I found another blog post about this topic and the writer says to use Sql(#"CREATE VIEW dbo.{ViewName} AS...") in Up method and Sql(#"DROP VIEW dbo.{ViewName};") in Down method. I added it as you didn't supplied the code from Up and Down migration methods. Maybe good idea will be to add SqlFile instead of Sql method.
There is also option to create customized code or sql generator and plug it in to migrations, but I guess it is not the things you are looking for.
Let me know in comment in case you need additional help.
Related links:
Using Views with Entity Framework Code First
EF CODE FIRST - VIEWS AND STORED PROCEDURES
Leveraging Views in Entity Framework
DbMigration.Sql Method (String, Boolean, Object)
DbMigration.SqlFile Method (String, Boolean, Object)
I have some issues with Entity framework 6.2. I change ef version and now I have a lot bug..
EF version: 6.2
Visual studio version: 15.5.2
.Net version: 4.7.1
OS: Windows 10 Pro 1709
1.NotMapped why not working any more with inheritance? My example class:
public class BaseClass {
public string MappedProp {get;set;}
public virtual string NotBeMappedProp {get;set;}
}
public class Test : BaseClass {
public string MappedProp {get;set;}
[NotMapped]
public override string NotBeMappedProp {get;set;}
}
add-migration not found entity framework on project. But I installed it already. Besides, I deleted all packages folder. However still continue same exception.
I open clean project but suprise... I have a new proplem. My foreign keys thrown an exception.
Unable to determine the principal end of an association between the
types x1 and x2. The principal end of this association must be
explicitly configured using either the relationship fluent API or data
annotations.
My code part looking like that:
public class Student{
.....
public string Name {get;set;}
public long? LocationId {get;set;}
[ForeingKey("LocationId")]
public Location Address {get;set;}
......
}
public class Location{
public long Id {get;set;}
........
}
It is working with previous version.
I have no migration, I updated my database, check table but entity framework still said, there is an migration.
the model backing the context has changed since the database was
created
Try add abstract modifier to BaseClass definition. NotMapped attribute should be at the lowest level. If you need to map overridden property you should map it with Column attribute directly in inherited class.
Try run command Install-Package EntityFramework -Version 6.2.0 -Project {{EFProjectName}} to reinstall package and reference it correctly.
You better want to specify ForeignKey attribute in Address class and its StudentId property(or whatever you call it). It is one-to-zero-or-one relationship.
Information about migrations are stored in the database table __MigrationHistory along with compiled db model to speed things up(checking everytime if code suits database is time consuming) and that is the reason you get that error. You have different compiled model in your code and different stored in the migration history. You can create empty migration running command Add-Migration -Name ManualDbUpdate -IgnoreChanges to overcomes this, but you must be sure code model and database model are equal. If not you are going to get exceptions.
I've always been a database oriented programmer, so up to this day, I've always used a database-driven approach to programming and I feel pretty confident in T-SQL and SQL Server.
I'm trying to wrap my head around the Entity Framework 6 code-first approach - and frankly - I'm struggling.
I have an existing database - so I did a Add New Item > ADO.NET Entity Data Model > Code-First from Database and I get a bunch of C# classes representing my existing database. So far so good.
What I'm trying to do now is explore how to handle ongoing database upgrades - both in schema as well as "static" (pre-populated) lookup data. My first gripe is that the entities that were reverse-engineered from the database are being configured with the Fluent API, while it seems more natural to me to create the new tables I want to have created as a C# class with data annotations. Is there any problems / issues with "mixing" those two approaches? Or could I tell the reverse-engineering step to just use data annotation attributes instead of the Fluent API altogether?
My second and even bigger gripe: I'm trying to create nice and small migrations - one each for each set of features I'm trying to add (e.g. a new table, a new index, a few new columns etc.) - but it seems I cannot have more than a single "pending" migration...... when I have one, and I modify my model classes further, and I try to get a second migration using add-migration (name of migration), I'm greeted with:
Unable to generate an explicit migration because the following explicit migrations are pending: [201510061539107_CreateTableMdsForecast]. Apply the pending explicit migrations before attempting to generate a new explicit migration.
Seriously ?!?!? I cannot have more than one, single pending migration?? I need to run update-database after every single tiny migration I'm adding?
Seems like a rather BIG drawback! I'd much rather create my 10, 20 small, compact, easy-to-understand migrations, and then apply them all in one swoop - no way to do this!?!? This is really hard to believe..... any way around this??
It is true that you can only have one pending migration open at a time during development. To understand why, you have to understand how the migrations are generated. The generator works by comparing the current state of your database (the schema) with the current state of your model code. It then effectively creates a "script" (a C# class) which changes the schema of the database to match the model. You would not want to have more than one of these pending at the same time or else the scripts would conflict with each other. Let's take an simple example:
Let's say I have a class Widget:
class Widget
{
public int Id { get; set; }
public string Name { get; set; }
}
and a matching table Widgets in the database:
Widgets
-------
Id (int, PK, not null)
Name (nvarchar(100), not null)
Now I decide to add a new property Size to my class.
class Widget
{
public int Id { get; set; }
public string Name { get; set; }
public int Size { get; set; } // added
}
When I create my migration, the generator looks at my model, compares it with the database and sees that my Widget model now has a Size property while the corresponding table does not have a Size column. So the resulting migration ends up looking like this:
public partial class AddSizeToWidget : DbMigration
{
public override void Up()
{
AddColumn("dbo.Widgets", "Size", c => c.Int());
}
public override void Down()
{
DropColumn("dbo.Widgets", "Size");
}
}
Now, imagine that it is allowed to create a second migration while the first is still pending. I haven't yet run the Update-Database command, so my baseline database schema is still the same. Now I decide to add another property Color to Widget.
When I create a migration for this change, the generator compares my model to the current state of the database and sees that I have added two columns. So it creates the corresponding script:
public partial class AddColorToWidget : DbMigration
{
public override void Up()
{
AddColumn("dbo.Widgets", "Size", c => c.Int());
AddColumn("dbo.Widgets", "Color", c => c.Int());
}
...
}
So now I have two pending migrations, and both of them are going to try to add a Size column to the database when they are ultimately run. Clearly, that is not going to work. So that is why there is only one pending migration allowed to be open at a time.
So, the general workflow during development is:
Change your model
Generate a migration
Update the database to establish a new baseline
Repeat
If you make a mistake, you can roll back the database to a previous migration using the –TargetMigration parameter of the Update-Database command, then delete the errant migration(s) from your project and generate a new one. (You can use this as a way to combine several small migrations into a larger chunk if you really want to, although I find in practice it is not worth the effort).
Update-Database –TargetMigration PreviousMigrationName
Now, when it comes time to update a production database, you do not have to manually apply each migration one at a time. That is the beauty of migrations -- they are applied automatically whenever you run your updated code against the database. During initialization, EF looks at the target database and checks the migration level (this is stored in the special __MigrationHistory table which was created when you enabled migrations on the database). For any migration in your code which has not yet been applied, it runs them all in order for you, to bring the database up to date.
Hope this helps clear things up.
Is there any problems / issues with "mixing" those two approaches?
No, there is no problem to mix them.
You can do more with fluent config than with data annotations.
Fluent config overrides data annotation when constructing the migration script.
You can use data annotations to generate DTOs and front-end/UI constraints dynamically - saves a lot of code.
Fluent API has class EntityTypeConfiguration which allows you to make domains (in DDD sense) of objects dynamically and store them - speeds up work with DbContext a lot.
I cannot have more than a single "pending" migration
Not 100% true. ( Maybe 50% but this is not a showstopper )
Yes, the DbMigrator compares your model "hash" to the database model "hash" when it generates the Db - so it blocks you before you make your new small migration. But this is not a reason to think you can not make small migration steps. I do only small migration steps all the time.
When you develop an app and you use your local db you apply the small migrations one by one as you develop functionality - gradually. At the end you deploy to staging/production all your small migrations in one dll with all the new functionality - and they are applied one by one.
I saw a lot of examples online but none that I could use from top to bottom about merging my own DbContext with Asp.net IdentityDbContext.
Can someone please walk me through it? I am at step 0, and what I want is to have the tables generated by ASP.net IdentityDbContext inside my own database, so that I can retain user data in my own database. How can I achieve that?
Thanx in advance :)
If I got you correct, you are trying to use your existing database, tables and existing users with asp.net identity framework.
First thing, according to my understanding, you can't merge your db context (MyDbContext) with 'IdentityDbContext', because context of asp.net identity framework tables has to be inherited from IdentityDbContext<YourUserTable>. But your other tables may inherited from DbContext.
Therefore you have to use two separate db contexts if you want to use identity framework build in method support, which is UserManager etc.
You can use your existing database with identity framework, you just need to correctly bind your database tables with identity framework EF code first approach using model binding.
There is a YouTube video tutorial which may help you to get some idea in order to achieve your task. Actually this video illustrates to use Identity 2.0 with existing database.
Part 1: https://www.youtube.com/watch?v=elfqejow5hM
Part 2: https://www.youtube.com/watch?v=JbSqi3Amatw
Hope this helps.
I'm not really sure what you're trying to achieve but check this question to see if it's of any help.
ASP.NET Identity DbContext confusion
Here's part of a walk-through I created. There are a few steps included specific to making it work with code first migrations but you should be able to accomplish what you want using these steps.
Start by creating a new ASP.NET MVC project. Call it Contacts if you want the included code to match. The authentication defaults to Individual User Accounts which is what we want in this case. Deselect Host in the Cloud for now. You can enter your publishing settings later. Once the project is created bring up the Package Manager Console and Install-Package EntityFramework. Now since we are doing Code First add a simple model class.
public class Contact {
public int ContactID { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
}
At this point you would usually add controllers and such but since this post is focusing on the data side of things we'll skip over all of that. Next we want to add our database context. Go ahead and add it right in the Models namespace.
public class ContactContext : IdentityDbContext {
public ContactContext()
: base("ContactContext") {
}
public DbSet<Contact> Contacts { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
public static ContactContext Create() {
return new ContactContext();
}
}
A couple of things to note here. Since we're consolidating the Identity tables into our application's context we want to inherit from IdentityDbContext instead of just DbContext. Also, I prefer not to use the generated "DefaultConnection" that gets created in Web.config so I'm passing "ContactContext" as the connection string name to the base constructor. We'll modify the connection string in a minute. If you're typing in the OnModelCreating method Visual Studio should add the call to base.OnModelCreating but if not make sure you add it since it's essential for building the identity tables. Although not essential, you can configure the modelBuilder not to pluralize table names. Add a Create method which is needed for the Identity code to use this context. Also, as you add code you'll need to right-click and Resolve to add the appropriate using statements.
As promised, here is the modified connection string to be updated in the web.config in the root of the site. The name property is changed to something that makes sense for the application and the AttachDbFilename and Initial Catalog values are changed to something a little more user friendly than the auto generated name.
<add name="ContactContext" connectionString="Data Source=
(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\ContactContext.mdf;Initial
Catalog=ContactContext;Integrated Security=True"
providerName="System.Data.SqlClient" />
Now go to the Models folder and open the IdentityModels.cs file. Cut the ApplicationUser class from here and paste it into your Contact.cs file. Again you'll have to resolve a few missing namespaces. At this point you can safely delete the IdentityModels.cs file. Since we've eliminated the ApplicationDbContext we'll need to do a find on ApplicationDbContext and replace it with ContactContext in a few places. You should be able to do a clean build.
I am new to MVC web application development.
I am trying to add a controller after adding my model and DbContext class.
But when i am trying to this controller using Entity framework it gives me an error of
Unable to cast object of type 'System.Data.Entity.Core.Objects.ObjectContext' to 'System.Data.Objects.ObjectContext'
I am using EF-6.1.1 (latest update)
Following are my Model and Context Class..
public class EmpDetails
{
[Key]
public int Id { get; set; }
public string EmpId { get; set; }
public string EmployeeName { get; set; }
}
public class ModelContext : DbContext
{
public DbSet<EmpDetails> Employee { get; set; }
}
When i am trying to add a controller I get following error.
Please suggest some solution to this problem. what is going wrong with it..
here is the process through which i am adding Controller
Entity Framework brought breaking changes between versions 5 and 6. In order for it to go completely open source, they moved all of the libraries out of band and they are now all completely within the EntityFramework assembly in NuGet. A side effect of this was that many of the namespaces for Entity Framework has changed:
The namespaces for DbContext and Code First types have not changed.
This means for many applications that use EF 4.1 or later you will not
need to change anything.
Types like ObjectContext that were previously in
System.Data.Entity.dll have been moved to new namespaces. This means
you may need to update your using or Import directives to build
against EF6.
The general rule for namespace changes is that any type in
System.Data.* is moved to System.Data.Entity.Core.*. In other words,
just insert Entity.Core. after System.Data. For example:
System.Data.EntityException => System.Data.Entity.Core.EntityException
System.Data.Objects.ObjectContext =>
System.Data.Entity.Core.Objects.ObjectContext
System.Data.Objects.DataClasses.RelationshipManager =>
System.Data.Entity.Core.Objects.DataClasses.RelationshipManager
The reason you are seeing the error is that you are using a previous version of MVC, which was targeting an earlier version of Entity Framework. The scaffolding is going to be assuming the old namespaces.
You can try upgrading to the newest version of MVC and your scaffolding will work again. Either that or downgrade EF6 (I don't recommend this, it has a lot of really great features). The third option is to manually fix your scaffolded code every time.
While using ASP.Net MVC 3/4, Entity framework assembly (.dll) would be automatically referenced with a lower version (5.0.0.0). And when you update this to a higher version an explicit type conversion is required for which you are getting this error. one way to fix this problem is, use the existing version of Entity Framework (5.0.0.0) without updating to higher version.