'Entity Framework Core 6 is auto incrementing non-key columns
Entity Framework Core 6 is auto-incrementing columns in my table that it shouldn't be.
I have a table in SQL Server defined like this:
CREATE TABLE [dbo].[Company]
(
[Company_ID] [int] IDENTITY(1,1) NOT NULL,
[CompanyName] [varchar](100) NOT NULL,
[CreatedOnUtc] [datetime] NOT NULL,
[AccountManager_ID] [int] NULL,
[Project_ID] [int] NOT NULL,
[Customer_ID] [int] NOT NULL
CONSTRAINT [PK_Company]
PRIMARY KEY CLUSTERED ([Company_ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Company]
ADD CONSTRAINT [DF_Company_CreatedOnUtc] DEFAULT (GETUTCDATE()) FOR [CreatedOnUtc]
GO
My entity is defined like this - I am explicitly defining the key column and that it's an identity.
[Table("Company")]
public partial class CompanyEntity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Required]
[DisplayName("Company ID")]
public int Company_ID { get; set; }
[Required]
[MaxLength(100)]
[DisplayName("Company Name")]
public string CompanyName { get; set; } = "";
[ForeignKey("AccountManager")]
[DisplayName("Account Manager ID")]
public int? AccountManager_ID { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Required]
[DisplayName("Created On Utc")]
public DateTime CreatedOnUtc { get; set; }
[ForeignKey("Project")]
//[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Required]
[DisplayName("Project ID")]
public int Project_ID { get; set; }
[ForeignKey("Customer")]
[Required]
[DisplayName("Customer ID")]
//[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Customer_ID { get; set; }
public AccountManagerEntity? AccountManager { get; set; }
public CustomerEntity Customer { get; set; } = new CustomerEntity();
public ProjectEntity Project { get; set; } = new ProjectEntity();
}
When I create and save a new CompanyEntity record
var company = new CompanyEntity()
{
CompanyName = "Test",
AccountManager_ID = 1
Project_ID = 1,
Customer_ID = 1,
};
Context.Company.Add(company);
await Context.SaveChangesAsync();
What I'd expect to see happen is a new record is added to the Company table that looks like:
Company_ID: xxx (auto-incremented in DB)
CompanyName: Test
AccountManager_ID: 1
Project_ID: 1
Customer_ID: 1
CreatedOnUtc: xx/xx/xxxx (auto generated)
Instead, what I see happening is that both the Project_ID and Customer_ID columns are being automatically incremented. So I'm ending up with records like this:
Company_ID: 1
CompanyName: Test
AccountManager_ID: 1
Project_ID: 1
Customer_ID: 1
CreatedOnUtc: 3/27/2022 18:13:00
Then if I delete this record and run my code again, I end up with another record (which I'd expect), but Project_ID and Customer_ID have incremented instead of using my values:
Company_ID: 2
CompanyName: Test
AccountManager_ID: 1
Project_ID: 2
Customer_ID: 2
CreatedOnUtc: 3/27/2022 18:13:00
I can see in the SQL Server profiler that EF is passing the incremented values. I'm sure this is because of some convention, but I have explicitly set attributes on these columns. AccountManager_ID seems to work OK - the only difference with that one is it's not a required field. I also tried adding
[DatabaseGenerated(DatabaseGeneratedOption.None)]
to Project_ID / Customer_ID, but that did not make any difference.
How do I tell EF, "don't do that"?
EDIT: OK, I figured out why this was happening. Because I'm creating an instance of both the CustomerEntity and ProjectEntity as default values, it's assuming I am also creating new records in these other tables. Removing the = new *Entity(); portion fixed the issue. I had only added these to make the compiler warning about the non-nullable property having a value when it exits the constructor go away. Oops.
public CustomerEntity Customer { get; set; } = new CustomerEntity();
public ProjectEntity Project { get; set; } = new ProjectEntity();
Solution 1:[1]
This code automatically creates new instances of Customer and Project and assignes new keys
public CustomerEntity Customer { get; set; } = new CustomerEntity();
public ProjectEntity Project { get; set; } = new ProjectEntity();
leave just like this
public CustomerEntity Customer { get; set; }
public ProjectEntity Project { get; set; }
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Serge |
