0

I've added a item into the context model and tried to save the changes, but even with valid values I'm getting error like below. Wonder how come it throws even after having all the valid values.

System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.

System.Data.Entity.Core.UpdateException: An error occurred while updating the entries. See the inner exception for details.

Oracle.ManagedDataAccess.Client.OracleException: ORA-01400: cannot insert NULL into ("DBO"."JOBS"."JOBID")

Code:

_dbContext.Jobs.Add(new Job(){JobId = 1902456,JobExecutionId = 390023,AccountId = 1,CommandType = "Type 1"});
_dbContext.SaveChanges();

internal class JobsConfiguration : EntityTypeConfiguration<Job>
{
        public JobsConfiguration()
        {
            ToTable("JOBS");
            HasKey(g => g.JobId);
            Property(g => g.JobId).HasColumnName("JOBID");
            Property(g => g.JobExecutionId).HasColumnName("JOBEXECUTION_ID");
            Property(g => g.AccountId).HasColumnName("ACCTID");
            Property(g => g.CommandType).HasColumnName("COMMANDTYPE");
        }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
nag
  • 920
  • 6
  • 27
  • 51
  • EF is probably expecting the database to assign a value to the PK. – Jeremy Lakeman Sep 16 '20 at 05:08
  • @JeremyLakeman Hi, When I insert the same data through direct query in the code I'm not getting any issues and data is inserted. Thank you. – nag Sep 16 '20 at 05:13
  • Entity Framework is passing a NULL because you told it that the JobId field is a Primary Key. It's NOT using the value you give it. Also Oracle is "special" in that you yourself have to tell it how to auto increment ID's. Yes, it's silly but that's how Oracle is. – Captain Kenpachi Sep 16 '20 at 06:21
  • Use this piece of code in your builder: Property(e => e.JobId).HasColumnName("JOBID") .ForOracleUseSequenceHiLo("SEQUENCE_NAME"); – Captain Kenpachi Sep 16 '20 at 06:27
  • @CaptainKenpachi There is a another column 'ID' exists which is used for auto increment. – nag Sep 16 '20 at 07:16

3 Answers3

0

When you use dbContext.Entity.Add(...) - your Entity PK (JobId) must be Zero, because Add() is Insert new value. If you want modify Entity with not Zero PK use instead dbContext.Entity.Update(...)

Then your first string must be:

_dbContext.Jobs.Add(new Job(){JobId = 1902456,JobExecutionId = 390023,AccountId = 1,CommandType = "Type 1"});

PS If you use Update() with Zero PK - it's insert NEW value in table (as you use Add()), example:

_dbContext.Jobs.Update(new Job(){JobId = 0,JobExecutionId = 390023,AccountId = 1,CommandType = "Type 1"});
Blackmeser
  • 101
  • 2
  • He is trying to add a new items, not modifying the existing one. For the update the Jobs.Update(..) code is ok. But can you specify how can he avoid null at jobId while inserting. – Abdulhakim Zeinu Sep 16 '20 at 08:42
  • If PK is not Zero - it's already not new item. Job?.JobId - is NULL when Add(JobId != 0) – Blackmeser Sep 16 '20 at 08:49
0

You have to tell Oracle to use a sequence to store and update the auto-incrementing PK from. It's something that I think is unique to Oracle:

internal class JobsConfiguration : EntityTypeConfiguration<Job>
{
        public JobsConfiguration()
        {
            ToTable("JOBS");
            HasKey(g => g.JobId);
            Property(g => g.JobId).HasColumnName("JOBID")
                                  .ForOracleUseSequenceHiLo("JOBS_SEQUENCE");//can be any name
            Property(g => g.JobExecutionId).HasColumnName("JOBEXECUTION_ID");
            Property(g => g.AccountId).HasColumnName("ACCTID");
            Property(g => g.CommandType).HasColumnName("COMMANDTYPE");
        }
}
Captain Kenpachi
  • 6,960
  • 7
  • 47
  • 68
0

You mentioned in the comments that the table has an id column. Maybe this leads to the errors you get, afaik EF assumes implicitly that this is the primary key. A solution can be to create an unique index for JobsId instead of making it the primary key or to explicitly ignore the id property. In EF Core an unique index is done like this:

entity.HasIndex(e => e.JobsId)
      .HasName("SYS_C00296922")
      .IsUnique();

entity.Property(e => e.JobsId)
      .HasColumnName("JobsId");

For EF 6.1 it's described here:

https://learn.microsoft.com/en-us/ef/ef6/modeling/code-first/fluent/types-and-properties

How to ignore properties is described here for EF Core and EF 6: https://stackoverflow.com/a/10385738/4712865

volkit
  • 1,173
  • 14
  • 21