I have the following migration I am trying to apply:
public override void Up()
{
CreateTable(
"dbo.pltblQuoteRoHSStatus",
c => new
{
QuoteRoHSStatusID = c.Int(nullable: false, identity: true),
Status = c.String(nullable: false, maxLength: 20),
})
.PrimaryKey(t => t.QuoteRoHSStatusID)
.Index(t => t.Status, unique: true, name: "IX_RoHSStatusIndex");
AddColumn("dbo.tblQuoteGeneral", "QuoteRoHSStatusID", c => c.Int(nullable: false));
CreateIndex("dbo.tblQuoteGeneral", "QuoteRoHSStatusID");
AddForeignKey("dbo.tblQuoteGeneral", "QuoteRoHSStatusID", "dbo.pltblQuoteRoHSStatus", "QuoteRoHSStatusID", cascadeDelete: true);
DropColumn("dbo.tblQuoteGeneral", "RoHS");
}
When I run update-database, I get the following error:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint
"FK_dbo.tblQuoteGeneral_dbo.pltblQuoteRoHSStatus_QuoteRoHSStatusID".
The conflict occurred in database "WebPDC", table
"dbo.pltblQuoteRoHSStatus", column 'QuoteRoHSStatusID'.
I do have existing records in tblQuoteGeneral. So, I need to assign a value (3) to QuoteRoHSStatusID for all existing records. I have tried the following modification to the auto generated migration shown above:
public override void Up()
{
CreateTable(
"dbo.pltblQuoteRoHSStatus",
c => new
{
QuoteRoHSStatusID = c.Int(nullable: false, identity: true),
Status = c.String(nullable: false, maxLength: 20),
})
.PrimaryKey(t => t.QuoteRoHSStatusID)
.Index(t => t.Status, unique: true, name: "IX_RoHSStatusIndex");
AddColumn("dbo.tblQuoteGeneral", "QuoteRoHSStatusID", c => c.Int(nullable: true));
Sql("UPDATE dbo.tblQuoteGeneral SET QuoteRoHSStatusID = 3");
AlterColumn("dbo.tblQuoteGeneral", "QuoteRoHSStatusID", c => c.Int(nullable: false));
CreateIndex("dbo.tblQuoteGeneral", "QuoteRoHSStatusID");
AddForeignKey("dbo.tblQuoteGeneral", "QuoteRoHSStatusID", "dbo.pltblQuoteRoHSStatus", "QuoteRoHSStatusID", cascadeDelete: true);
DropColumn("dbo.tblQuoteGeneral", "RoHS");
}
I am still getting the same error. What am I doing wrong?
EDIT: I would like to accomplish the above in one migration.
I figured out what my problem was. I'll post it just for anyone else that may find it useful. I did everything right in my modification to the auto generated migration except for populating the pltblQuoteRoHSStatus table with values. How can I run UPDATE dbo.tblQuoteGeneral SET QuoteRoHSStatusID = 3 without already having a record in pltblQuoteRoHSStatus with a ID of 3. That is what was causing the error due to the foreign key constraint.
So, here is my working code:
public override void Up()
{
CreateTable(
"dbo.pltblQuoteRoHSStatus",
c => new
{
QuoteRoHSStatusID = c.Int(nullable: false, identity: true),
Status = c.String(nullable: false, maxLength: 20),
})
.PrimaryKey(t => t.QuoteRoHSStatusID)
.Index(t => t.Status, unique: true, name: "IX_RoHSStatusIndex");
AddColumn("dbo.tblQuoteGeneral", "QuoteRoHSStatusID", c => c.Int(nullable: true));
Sql("INSERT INTO dbo.pltblQuoteRoHSStatus (Status) VALUES ('Compliant') ");
Sql("INSERT INTO dbo.pltblQuoteRoHSStatus (Status) VALUES ('Noncompliant') ");
Sql("INSERT INTO dbo.pltblQuoteRoHSStatus (Status) VALUES ('Unknown') ");
Sql("UPDATE dbo.tblQuoteGeneral SET QuoteRoHSStatusID = 3");
AlterColumn("dbo.tblQuoteGeneral", "QuoteRoHSStatusID", c => c.Int(nullable: false));
CreateIndex("dbo.tblQuoteGeneral", "QuoteRoHSStatusID");
AddForeignKey("dbo.tblQuoteGeneral", "QuoteRoHSStatusID", "dbo.pltblQuoteRoHSStatus", "QuoteRoHSStatusID", cascadeDelete: true);
DropColumn("dbo.tblQuoteGeneral", "RoHS");
}
Do it in two migrations:
In the first, you add the field with the (nullable) foreign key. Apply that migration to the database, then update the field in the database with a script.
Then add your second migration to make the field non-nullable.
Related
migrationBuilder.CreateTable(
name: "DKPositions",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
ProviderEventId = table.Column<string>(type: "text", nullable: false),
LastUpdated = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_DKPositions", x => x.Id);
});
I have been searching for some documents talking about partitioning tables in code-first Entity Framework design but I haven't been able to find anything. I am trying to partition this table by LastUpdated.
Is this possible with Entity Framework and a code-first design?
I am developing an mvc App using Code First Approach. I want to generate VarcharID Based on the Identity Column Value. I know How to Achieve this in SQL. I want to Know how can I write the following SQL Query in VoidUp() Method
SQL Query I want to Write
CREATE TABLE [dbo].[EmployeeMaster](
[ID] [int] IDENTITY(1,1) NOT NULL,
[PreFix] [varchar](50) NOT NULL,
[EmployeeNo] AS ([PreFix]+ RIGHT('0000000' + CAST(Id AS VARCHAR(7)), 7)) PERSISTED,
[EmployeeName] VARCHAR(50),
CONSTRAINT [PK_AutoInc] PRIMARY KEY ([ID] ASC)
)
My Code in Migration.cs Void Up method
CreateTable(
"dbo.Employees",
c => new
{
ID = c.Int(nullable: false, identity: true),
EmployeePrefix = c.String(),
EmployeeEmpNo = c.String(), // Want to Change stuff Here
EmployeeName = c.String(nullable: false),
})
.PrimaryKey(t => t.ID);
You can write the data you need in "Seed" method of "Configuration.cs" file. You can find an example here. Your code will look smth like this:
foreach (var entity in context.EmployeeMaster.Where(em => string.IsNullOrEmpty(em.EmployeeNo))
{
var idStr = "0000000" + entity.Id.ToString();
entity.EmployeeNo = entity.Prefix + idStr.SubString(idStr.Length - 7);
}
context.SaveChanges();
Hope it will help you.
I'm using EF code first and I want to create a new table and insert values from an existing table into it.
public override void Up()
{
CreateTable(
"dbo.UserCulture",
c => new
{
UserCultureId = c.Int(false, true),
Id = c.Int(false),
IsSelected = c.Boolean(false),
Culture = c.String(false, 10),
UserLevel = c.Int(false),
CurrentScore = c.Int(false),
TimelinePercentage = c.String(false, 3),
NumberOfGamesPlayed = c.Int(false)
})
.PrimaryKey(k => k.UserCultureId)
.ForeignKey("dbo.AskUser", k => k.Id)
.Index(t => t.Id);
Sql("INSERT INTO UserCulture(UserCultureId, Id, IsSelected, Culture, UserLevel, CurrentScore, TimelinePercentage, NumberOfGamesPlayed)" +
"SELECT newid(), UserId, 1, CreatedCulture, UserLevel, CurrentScore, TimelinePercentage, NumberOfGamesPlayed FROM AskUser");
}
When I ran this migration it created the table but it was empty. Does anyone know what I should do?
newid() is for uniqueidentifier?
Can you try removing that column in the insert statement?
Sql("INSERT INTO UserCulture(Id, IsSelected, Culture, UserLevel, CurrentScore, TimelinePercentage, NumberOfGamesPlayed)" +
"SELECT UserId, 1, CreatedCulture, UserLevel, CurrentScore, TimelinePercentage, NumberOfGamesPlayed FROM AskUser");
I am attempting to change the default column type of a string field to varchar for a specific table (Contacts table) in my DB, using codefirst migrations with EF6.
I first attempted to implement this in my context class using:
modelBuilder.Properties<string>().Configure(c => c.HasColumnType("varchar"));
This attempts to remap the entire db's string fields to varchar and produces a lengthy migration. I have used this migration as a template to produce a migration updating only the columns of my Contacts table. I now have a migration which is:
public override void Up()
{
AlterColumn("dbo.Contacts", "FirstName", c => c.String(maxLength: 8000, unicode: false));
AlterColumn("dbo.Contacts", "LastName", c => c.String(maxLength: 8000, unicode: false));
AlterColumn("dbo.Contacts", "Company", c => c.String(maxLength: 8000, unicode: false));
AlterColumn("dbo.Contacts", "Position", c => c.String(maxLength: 8000, unicode: false));
AlterColumn("dbo.Contacts", "Notes", c => c.String(maxLength: 8000, unicode: false));
}
public override void Down()
{
AlterColumn("dbo.Contacts", "Notes", c => c.String());
AlterColumn("dbo.Contacts", "Position", c => c.String());
AlterColumn("dbo.Contacts", "Company", c => c.String());
AlterColumn("dbo.Contacts", "LastName", c => c.String());
AlterColumn("dbo.Contacts", "FirstName", c => c.String());
}
This is precisely what I want to occur, however when trying to update my database I see the following error:
Tables without a clustered index are not supported in this version of SQL Server.
Please create a clustered index and try again.
Could not drop constraint. See previous errors.
The statement has been terminated.
I'm not sure what this error means, but I wondered if there was a standard way of getting past this error to apply the migration I have created.
Or alternatively is there a different way to accomplish my goal of setting the string default to varchar for my Contacts table, ensuring no impact on my current interactions with the table in code and no data loss.
Worth adding the my SQL db is hosted in Azure.
Here I have a migration of CodeFirst using EF6
public override void Up()
{
CreateTable(
"dbo.MyTable",
c => new
{
Id = c.Int(nullable: false, identity: true),
Date = c.DateTime(nullable: false, defaultValueSql: "GETUTCDATE()"),
})
.PrimaryKey(t => t.Id);
}
But we found that the Date could not be customized at insert. So we need a migration to delete the defaultValueSql parameter on Date column.
I've tried using AlterColumn without defaultValueSql parameter,
public override void Up()
{
AlterColumn("dbo.MyTable", "Date", c => c.DateTime(nullable: false));
}
public override void Down()
{
AlterColumn("dbo.MyTable", "Date", c => c.DateTime(nullable: false, defaultValueSql: "GETUTCDATE()"));
}
it works neither for inserting and updating the Date, nor to the definition of table.
CREATE TABLE [dbo].[MyTable] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Date] DATETIME DEFAULT (getutcdate()) NOT NULL,
);
Anyone has run into this situation, please ?
Actually, in the database, there was a Constraint created for the defaultValueSql, and I think this parameter works by the sys table, rather than MyTable, which results in ineffective of my AlterColumn.
Eventually, I created some original SQL commands for my purpose like following:
public override void Up()
{
Sql(#"
DECLARE #sql NVARCHAR(MAX)
SELECT #sql = N'alter table [EffectiveDonations] drop constraint ['+d.name+N']'
FROM sys.default_constraints
WHERE d.parent_object_id = OBJECT_ID(N'MyTable')
AND col_name(parent_object_id, parent_column_id) = N'Date'
EXEC (#sql)
");
Sql("PRINT 'Information: delete [defaultvaluesql]';");
}
public override void Down()
{
Sql(#"ALTER TABLE [MyTable] ADD DEFAULT getutcdate() FOR [Date]");
Sql("PRINT 'Information: create [defaultvaluesql] for column [Date] of table [MyTable]';");
}
Share to hope this could be help to others.
Try it in two stages:
public override void Up()
{
AlterColumn("dbo.MyTable", "Date", c => c.DateTime(nullable: true,
defaultValue: "NULL"));
AlterColumn("dbo.MyTable", "Date", c => c.DateTime(nullable: false));
}