d512
d512

Reputation: 34273

How to fix error in code generated by Entity Framework

I am using code first migrations with an existing database. I used the reverse engineering feature to generate all the initial entities. However, the database was not well designed and one of the tables did not have a primary key designated. Apparently Entity Framework did its best to infer the primary key and didn't get it right. It looks like it decided to make two fields a compound primary key.

I want to actually remove one of the fields that it mistakenly thinks is part of the primary key and it's resulting in errors.

Here is the original schema of the table when the entity was created for it:

CREATE TABLE [dbo].[Table1](
    [The_ID] [bigint] IDENTITY(1,1) NOT NULL,
    [Field_1] [varbinary](max) NULL,
    [Field_2] [bigint] NULL,
    [Field_3] [varbinary](max) NULL,
    [Field_4] [datetime] NULL,
    [Field_5] [bit] NOT NULL
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Table1] ADD  CONSTRAINT [DF_Table1_F5]  DEFAULT ((0)) FOR [Field_5]
GO

The_ID should have been designated as the primary key but as you can see it was not. Here is class the Visual Studio generated:

public partial class Table1
{
    [Key]
    [Column(Order = 0)]
    public long The_ID { get; set; }

    public byte[] Field_1 { get; set; }

    public long? Field_2 { get; set; }

    public byte[] Field_3 { get; set; }

    public DateTime? Field_4 { get; set; }

    [Key]
    [Column(Order = 1)]
    public bool Field_5 { get; set; }
}

It apparently decided to make The_ID and Field_5 into a compound primary key. At least that's how I'm interpreting this code. Now, I actually need to remove Field_5 from the table. I created an migration to do this, but since Entity Framework thinks its part of a primary key its doing weird things like dropping the primary key and re-adding it, which is resulting in errors. Here is the generated migration code:

public override void Up()
{
    DropPrimaryKey("dbo.Table1");
    AlterColumn("dbo.Table1", "The_ID", c => c.Long(nullable: false, identity: true));
    AddPrimaryKey("dbo.Table1", "The_ID");
    DropColumn("dbo.Table1", "Field_5");
}

Running this results in the following error:

ALTER TABLE [dbo].[Table1] DROP CONSTRAINT [PK_dbo.Table1] System.Data.SqlClient.SqlException (0x80131904): 'PK_dbo.Table1' is not a constraint.

So how do I get myself out of this mess?

I tried removing the [Key] attributes from The_ID and Field_5 and creating a dummy migration using

Add-Migration dummy -IgnoreChanges

with the thought that I could then add the [Key] attribute back to The_ID and remove Field_5 but it won't let me create a migration unless at least one field is designated with the [Key] attribute. But if I do that to get the dummy migration in place then I can't do it in a real migration so I'm not able to actually designate The_ID as the primary key using code first migrations.

Any ideas?

Upvotes: 0

Views: 525

Answers (1)

codeworx
codeworx

Reputation: 2745

If you have a Table without Primary Key in you Database EntityFramework will interpret every not nullable column in the table as part of the Primary Key.

In this case you could just remove the first two lines from the generated Migration, because there is no primary key to drop. EntityFramework just does not know about this fact.

public override void Up()
{
    //DropPrimaryKey("dbo.Table1");
    //AlterColumn("dbo.Table1", "The_ID", c => c.Long(nullable: false, identity: true));
    AddPrimaryKey("dbo.Table1", "The_ID");
    DropColumn("dbo.Table1", "Field_5");
}

Upvotes: 1

Related Questions