EntityFramework migration: AlterColumn DateTime to DateTimeOffset - entity-framework

In "Code First" EF approach, I've changed the type of a property:
Before:
DateTime Date { get; set; }
After:
DateTimeOffset Date { get; set; }
And then I executed (Package Manager Console):
Add-Migration Foo
Which created this code:
public partial class Foo : DbMigration
{
public override void Up()
{
AlterColumn("dbo.Foos", "Date", c => c.DateTimeOffset(nullable: false, precision: 7));
}
public override void Down()
{
AlterColumn("dbo.Foos", "Date", c => c.DateTime(nullable: false));
}
}
But this is not working when executing the update (Package Manager Console):
Update-Database
Error:
Error Number:5074,State:1,Class:16 The object
'DF__Foo__2B2A60FE' is dependent on column 'Date'.
ALTER TABLE ALTER COLUMN Date failed because one or more objects
access this column.
How can I solve this? I'm not referencing this column in other parts (there are no indexes)

As Ivan Stoev said in the comments, this is fixed by updating to EF 6.2 (I was using EF 6.1.3)

Related

EF 6.2.0 shows error 'The model backing context has changed since the database was created' when I update a column on the DB

I am trying to increase the column lenght, by using EF 6.2.0, VS 2019 and SQL Server Management Studio 18,12,1 by creating a new migration and updating manually the model, so that:
I follow the next steps
1.Alter Model by using the next attributes:
[Required]
[StringLength(300)]
public string MyColumn { get; set; }
2. Create new Migration
public override void Up()
{
AlterColumn("myTable", "myColumn", c => c.String(maxLength: 300));
}
public override void Down()
{
AlterColumn("myTable", "myColumn", c => c.String(maxLength: 255));
}
3.Run the Migration in the Package Manager Console
PM> Update-database -force
4.Checking the DB Changes abd the column maxLenght is updated properly
[1]
5.Debug the application but got the next error:
"The model backing context has changed since the database was created"
Any thoughts, will be appreciated!
I solve it by adding the SetInitializer method over the DataContext constructor:
public ReportsDataContext()
: base(Settings.GetConnectionString())
{
Configuration.LazyLoadingEnabled = false;
Configuration.ProxyCreationEnabled = false;
//*********Adding this line*********
Database.SetInitializer<ReportsDataContext>(null);
InitContext();
}

Adding Entity Framework core code first sublass with existing property name

What is best/a good practise in the following situation when using TPH inheritance in Entity Framework?:
I have
abstract class Base
{
...
}
class Sub1
{
public int Amount {get;set;}
}
and a DbContext with:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Sub1>();
}
public DbSet<Base> Bases { get; set; }
Now I add
class Sub2
{
public int Amount { get; set; }
}
and
modelBuilder.Entity<Sub2>();
Before adding Sub2, Sub1.Amount was mapped to a "Amount" column in the Bases table. After adding Sub2, Sub1.Amount is mapped to a "Sub1_Amount" column and Sub2.Amount is mapped to the "Amount" column. The table has data in it, so the new "Sub1_Amount" column are all nulls. When I try to run the system, I get
An exception occurred while reading a database value for property 'Sub1.Amount'. The expected type was 'System.Int32' but the actual value was null.
I understand why this is happening...but I thought Migrations would handle this.
Does anyone one know how to handle this? Thanks!

EF6 code first and VIEW

I would like to add a VIEW to the database, and query the data from this VIEW using L2E. I use migrations for maintaining database schema.
I added one class that should MAP to a VIEW columns. As an example, this class has only two properties
[Table("View_Data")]
public class ViewData
{
[Key]
public int Id { get; set; }
public int PropertyA { get; set; }
}
public class ViewDataMap : EntityTypeConfiguration<ViewData>
{
public ViewDataMap ()
{
this.ToTable("View_Data");
this.HasKey(t => t.Id);
}
}
I added ViewDataMap to OnModelCreating, as with any other Table mappings. I added DbSet ViewDatas.
When I executed
add-migration preview
it created new migration with CreateTable command. Since I do not want to create a table, but only a view, I replaced in UP() CreateTable with Sql("CREATE VIEW...")
Still, EF complains about pending changes in database, and still wants to create new migration with CreateTable()...
How can prevent EF to create new table, but use VIEW instead?
As Steve suggested in the comment, I forgot to do update-database, then all works as expected.

Add-Migration not adding column to existing table in Entity Framework Core

I am trying to add a new column to my existing table in database, i am specifying new field into class and running Add-Migration command but everytime it is creating a migration class for whole table with CreateTable method instead of AddColumn. Below is the class and generated migration class codes.
public class UserSetup
{
public int Id { get; set; }
public string Name { get; set; }
public bool Age{ get; set; } // New Field Added
}
But for new field it is creating migration class for full table as shown below:
public partial class AddUserSetup_1 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "UserSetup",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Name= table.Column<string>(nullable: false),
Age= table.Column<int>(nullable: false),
},
constraints: table =>
{
table.PrimaryKey("PK_UserSetup", x => x.Id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "UserSetup");
}
}
Also in Add-Migration it is giving me the following error but even migration class is getting created.
System.UnauthorizedAccessException: Access to the path 'C:\Projects\PSM\Portal\src\Portal\Migrations\ApplicationDbContextModelSnapshot.cs' is denied.
This can happen if you don't have the { get; set; } accessors. Clearly not the case in your code example, though.
Comment your new Age field
//public bool Age{ get; set; } // New Field Added
Open the "Server Explorer" window and make sure you can see your table in "Data Connections"
Run in Package Manager Console:
Enable-Migrations
Add-Migration InitialCreate –IgnoreChanges
Update-Database
Now EF should recognize your DB
Now uncomment your new "Age" field
Run in Package Manager Console:
Add-Migration AddUserSetup_1
Update-Database
Comment:
When you write "Enable-Migrations" maybe you will need to add -Force like that:
Enable-Migrations -Force
If you are using TFS make sure to checkout for edit your 'ApplicationDbContextModelSnapshot.cs' file. It will work just fine!

EF Code First 5.0.rc Migrations doesn`t update Identity property

Say, we are using EF Code First and we have this simple model:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace EFCodeFirstIdentityProblem.Models
{
public class CAddress
{
public int ID { get; set; }
public string Street { get; set; }
public string Building { get; set; }
public virtual CUser User { get; set; }
}
public class CUser
{
public int ID { get; set; }
public string Name { get; set; }
public string Age { get; set; }
[Required]
public virtual CAddress Address { get; set; }
}
public class MyContext : DbContext
{
public DbSet<CAddress> Addresses { get; set; }
public DbSet<CUser> Users { get; set; }
}
}
Like this, CAddress would be principal end of this 1:0..1 relationship.
Next we add connection string to Web.Config (I use MSSQL 2008 R2), make a controller that uses this model, run. EF Code First creates tables for us as expected:
So, let's assume we made a mistake, and in fact we want CUser to be principal end of this 0..1:1 relationship. So we make changes:
...
[Required]
public virtual CUser User { get; set; }
...
...
public virtual CAddress Address { get; set; }
...
Build, then in Package Manager Console run and add some migration:
PM> Enable-Migrations
Checking if the context targets an existing database...
Detected database created with a database initializer. Scaffolded migration '201208021053489_InitialCreate' corresponding to existing database. To use an automatic migration instead, delete the Migrations folder and re-run Enable-Migrations specifying the -EnableAutomaticMigrations parameter.
Code First Migrations enabled for project EFCodeFirstIdentityProblem.
PM> Add-Migration ChangeDependency
Scaffolding migration 'ChangeDependency'.
The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration 201208021157341_ChangeDependency' again.
PM>
Here what we`ve been given for "ChangeDependency" migration:
namespace EFCodeFirstIdentityProblem.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class ChangeDependency : DbMigration
{
public override void Up()
{
DropForeignKey("dbo.CUsers", "ID", "dbo.CAddresses");
DropIndex("dbo.CUsers", new[] { "ID" });
AlterColumn("dbo.CAddresses", "ID", c => c.Int(nullable: false));
AlterColumn("dbo.CUsers", "ID", c => c.Int(nullable: false, identity: true)); //identity: true - this is important
AddForeignKey("dbo.CAddresses", "ID", "dbo.CUsers", "ID");
CreateIndex("dbo.CAddresses", "ID");
}
public override void Down()
{
DropIndex("dbo.CAddresses", new[] { "ID" });
DropForeignKey("dbo.CAddresses", "ID", "dbo.CUsers");
AlterColumn("dbo.CUsers", "ID", c => c.Int(nullable: false));
AlterColumn("dbo.CAddresses", "ID", c => c.Int(nullable: false, identity: true));
CreateIndex("dbo.CUsers", "ID");
AddForeignKey("dbo.CUsers", "ID", "dbo.CAddresses", "ID");
}
}
}
Importand part is:
AlterColumn("dbo.CUsers", "ID", c => c.Int(nullable: false, identity: true));
So CUsers.ID must now become Identity in DB. Let's commit this changes to DB:
PM>
PM> Update-Database -Verbose
Using StartUp project 'EFCodeFirstIdentityProblem'.
Using NuGet project 'EFCodeFirstIdentityProblem'.
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Target database is: 'EFTest' (DataSource: (local), Provider: System.Data.SqlClient, Origin: Configuration).
Applying code-based migrations: [201208021157341_ChangeDependency].
Applying code-based migration: 201208021157341_ChangeDependency.
ALTER TABLE [dbo].[CUsers] DROP CONSTRAINT [FK_dbo.CUsers_dbo.CAddresses_ID]
DROP INDEX [IX_ID] ON [dbo].[CUsers]
ALTER TABLE [dbo].[CAddresses] ALTER COLUMN [ID] [int] NOT NULL
ALTER TABLE [dbo].[CUsers] ALTER COLUMN [ID] [int] NOT NULL
ALTER TABLE [dbo].[CAddresses] ADD CONSTRAINT [FK_dbo.CAddresses_dbo.CUsers_ID] FOREIGN KEY ([ID]) REFERENCES [dbo].[CUsers] ([ID])
CREATE INDEX [IX_ID] ON [dbo].[CAddresses]([ID])
[Inserting migration history record]
Running Seed method.
PM>
There is no SQL instructions given by Migrations of CUsers.ID becoming Identity column in DB. So, because of this there is a problem:
(updated database)
So, User is principal end now, and has to have ID Identity: "YES" flag, but Identity is still "NO". And Address is dependent end, has to have ID Identity "NO", but is still "YES". So I can't add new User to User table, because new ID is not generated for new instance.
If I drop whole database, EF Code First creates new tables from scratch properly, so this is a problem only of Migrations.
What do I do in this situation? Is this EF Migrations bug?
I'm not sure if it is a bug because there is another problem - you cannot alter existing column to identity or remove identity. I can imagine that this is considered as fully manual migration to make it clear that you must move data.