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?
Related
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 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.
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.
We are using EF on the project and need to create 1:1 relation between 2 tables in the database (FundMaterList and FundMeta).
The first (FundMasterList) was created using db first approach and it has the following column as primary key :
[PerformanceID] [char](10) NOT NULL
and this primary constraint:
CONSTRAINT [PK_FundMasterList] PRIMARY KEY CLUSTERED
([PerformanceID] ASC)
WITH (PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
Second (FundMeta) was created using code-first approach and has the following declaration:
public class FundMeta
{
[Key]
[StringLength(10)]
[Column("PerformanceID")]
public string InstId { get; set; }
...
}
and the following mapping
modelBuilder.Entity<FundMetadataEntity>()
.Property(e => e.InstId)
.IsFixedLength()
.IsUnicode(false);
modelBuilder.Entity<FundEntity>()
.HasOptional(e => e.FundMeta)
.WithRequired(e => e.Fund)
.WillCascadeOnDelete();
FundMeta and Fund are declared as virtuals. When I am running database update I get the following error message:
Column 'dbo.FundMasterList.PerformanceID' is not the same data type as referencing column 'FundMetadats.PerformanceID' in foreign key 'FK_dbo.FundMetas_dbo.FundMasterList_PerformanceID'.
Could not create constraint. See previous errors.
When I remove creating relations everithing works fine and column in the table FundMeta has the same type as in FundMasterList. It seems that creating relation try to "overwrite" this constraint:
modelBuilder.Entity<FundMetadataEntity>()
.Property(e => e.InstId)
.IsFixedLength()
.IsUnicode(false);
EDIT:
When I generated migration script I've noticed the following changes:
Without relation it looks OK:
AlterColumn("dbo.FundMeta", "PerformanceID",
c => c.String(nullable: false, maxLength: 10, fixedLength: true, unicode: false));
After the relationship added:
DropPrimaryKey("dbo.FundMeta");
AlterColumn("dbo.FundMeta", "PerformanceID", c => c.String(nullable: false, maxLength: 10));
AddPrimaryKey("dbo.FundMeta", "PerformanceID");
It means that limitation on fixedLength: true, unicode: false was lost.
When add this limitation manually in migration script everything works fine. Any other solutions possible?
Steve is true.
With no other information String leads to nvarchar.
So you are trying to create a constraint between char[10] and nvarchar[10].
You have to force the type of your PK by using HasColumnType("char") as stated by Steve.
NotUnicode may not be enough as you will get varchar(10)
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));
}