Entity Framework Core 6 自动递增非键列
Entity Framework Core 6 在我的表中自动增加了不应该的列。
我在 SQL Server 中有一个表定义如下:
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
我的实体定义如下 - 我显式定义键列并且它是一个标识。
[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();
}
当我创建并保存新的 CompanyEntity 记录时,
var company = new CompanyEntity()
{
CompanyName = "Test",
AccountManager_ID = 1
Project_ID = 1,
Customer_ID = 1,
};
Context.Company.Add(company);
await Context.SaveChangesAsync();
我期望看到的情况是将新记录添加到 Company
表中,如下所示:
Company_ID: xxx (auto-incremented in DB)
CompanyName: Test
AccountManager_ID: 1
Project_ID: 1
Customer_ID: 1
CreatedOnUtc: xx/xx/xxxx (auto generated)
相反,我看到的情况是 >Project_ID
和 Customer_ID
列会自动递增。因此,我最终会得到这样的记录:
Company_ID: 1
CompanyName: Test
AccountManager_ID: 1
Project_ID: 1
Customer_ID: 1
CreatedOnUtc: 3/27/2022 18:13:00
然后,如果我删除此记录并再次运行我的代码,我最终会得到另一条记录(这是我所期望的),但 Project_ID 和 Customer_ID 已递增,而不是使用我的值:
Company_ID: 2
CompanyName: Test
AccountManager_ID: 1
Project_ID: 2
Customer_ID: 2
CreatedOnUtc: 3/27/2022 18:13:00
I可以在 SQL Server Profiler 中看到 EF 正在传递递增的值。我确信这是因为某些约定,但我已在这些列上显式设置属性。 AccountManager_ID
似乎工作正常 - 与该字段的唯一区别是它不是必填字段。我还尝试添加
[DatabaseGenerated(DatabaseGeneratedOption.None)]
到 Project_ID
/ Customer_ID
,但这没有任何区别。
我如何告诉 EF“不要这样做”?
编辑:好的,我明白为什么会发生这种情况。因为我正在创建 CustomerEntity 和 ProjectEntity 的实例作为默认值,所以假设我也在这些其他表中创建新记录。删除 = new *Entity();
部分解决了该问题。我添加这些只是为了让编译器在退出构造函数时发出有关具有值的不可为空属性的警告消失。哎呀。
public CustomerEntity Customer { get; set; } = new CustomerEntity();
public ProjectEntity Project { get; set; } = new ProjectEntity();
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();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
此代码自动创建客户和项目的新实例,并分配新的钥匙
请假
This code automatically creates new instances of Customer and Project and assignes new keys
leave just like this