I'm getting an error:
Cannot insert explicit value for identity column in table 'ScheduleTransactionLink' when IDENTITY_INSERT is set to OFF
The SQL generated is:
INSERT INTO [ScheduleTransactionLink] ([Id], [CreatedByUserId], [CreatedDate], [Deleted], [LastUpdateDate], [LastUpdatedByUserId], [PaymentNumber], [ScheduleId])
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7);`
So obviously the issue is something related to passing in an Id value, and I have IDENTITY INSERT to on. But I'm not sending an Id.
My table is defined as:
internal class ScheduleTransactionLink : EntityAudit
{
[Required, Key]
public int Id { get; set; }
[Required]
public Schedule Schedule { get; set; }
[Required]
public Transaction Transaction { get; set; }
[Required]
public int PaymentNumber { get; set; }
}
Same as all my other tables. But only this bit of code is failing. As I can see, the generated SQL is sending 'Id'.
This only started happening after I added a navigational property to this table for a very complete query elsewhere.
modelBuilder.Entity<Transaction>()
.HasOne(x => x.ScheduleTransactionLink)
.WithOne(t => t.Transaction)
.HasForeignKey<ScheduleTransactionLink>();
An example of how I save my entity is here:
ScheduleTransactionLink link = new ScheduleTransactionLink
{
CreatedByUserId = _jwt.UserId,
CreatedDate = DateTime.UtcNow,
PaymentNumber = paymentNumber,
Schedule = schedule,
Transaction = transaction
};
_context.ScheduleTransactionLink.Add(link);
var result = await _context.SaveChangesAsync();
It's on the SaveChangesAsync where it errors out.
I have also added this code to OnModelCreating:
modelBuilder.Entity<ScheduleTransactionLink>(entity =>
{
entity.Property(e => e.Id).UseIdentityColumn();
});
Looking at the database, the table is created correctly:
CREATE TABLE [dbo].[ScheduleTransactionLink]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
....
How do I stop EF from sending the PK value?
CodePudding user response:
I suspect that EF isn't able to fully work out how your 1:1 entities relate. It looks like it's grasped that Transaction is the principal but i suspect it's trying to forge a relationship by putting the transaction ID into the ScheduleTransaction.Id - that's an independent PK in its own right, not an FK of transaction ID.. You might have to help it out some by doing:
internal class ScheduleTransactionLink : EntityAudit
{
[ Key]
public int Id { get; set; }
[Required]
public Schedule Schedule { get; set; }
public int TransactionId { get; set; }
[Required]
public Transaction Transaction { get; set; }
[Required]
public int PaymentNumber { get; set; }
}
modelBuilder.Entity<Transaction>()
.HasOne(x => x.ScheduleTransactionLink)
.WithOne(t => t.Transaction)
.HasForeignKey<ScheduleTransactionLink>(stl => stl.TransactionId);
It might work to not add a TransactionId and just:
modelBuilder.Entity<Transaction>()
.HasOne(x => x.ScheduleTransactionLink)
.WithOne(t => t.Transaction)
.HasForeignKey<ScheduleTransactionLink>(stl => stl.Transaction);
..but it's not something I've come across/can test atm and the docs for configuring 1:1s do specifically have the "int Id property and nominate it in the fluent" approach. Give it a test, and if it works/doesn't let me know and I'll amend the answer
