EF6 SaveChanges fails claiming field supplied is NULL

Viewed 30

I have been using EF for awhile but I am not sure what is missing as I am following a pattern I have used several times in the past. This is the SQL table definition:

   Table LogTable
      Columns
         LogID (int, Identity)
         fk_ref (int, not null)
         action (nvarchar(60))
         notes  (nvarchar(200))

This is the code (names changed for ease of reading/understanding)

    using(myEntity _me = new myEntity)
    {
        LogTable _lt = new LogTable();
        _lt.fk_ref = 10;
        _lt.action = "Some action";
        _lt.notes = "even more text";
        _me.LogTable.Add(_lt);
        _me.SaveChanges();
    }

This is where it blows up claiming that the field "fk_ref" is null. When I go to the edmx and ModelBrowser all the fields are represented. When I check the select SQL on the table name "_me.LogTable" during debug the SELECT statement is missing the field it claims as NULL.
I hope I have given enough information to turn on the light bulb in my head.

NOTE: I have tried dropping and re-adding the table. Gone as far as drop, clean, rebuild, re-add and no change. Would really appreciate any help.

UPDATE: Since this is new functionality I took the liberty of breaking the foreign key enforcement on the reference table and ran the code as demonstrated above. I also removed the Not Null limitation. It wrote out the record but put a NULL in the fk_ref field.

UPDATE 2 As someone asked for it. This is the CS modified to match the shortened definition above.

        public LogTable()
        {
            this.fk_ref = 0;
        }
    
        public int LogID { get; set; }
        public Nullable<int> fk_ref { get; set; }
        public string action { get; set; }
        public string notes { get; set; }

prior to the changes I mentioned in the first update it was

        public LogTable()
        {
        }
    
        public int LogID { get; set; }
        public fk_ref { get; set; }
        public string action { get; set; }
        public string notes { get; set; }

UPDATE 3 moving ahead with this I saved a record via the code above and while debugging checked the DB for the value inserted in the fk_ref field and it was null. So, i fetch the record back to the app via the LogID, manually set the field value to a random number and called SaveChanges again. Still null. Here is the code following the SaveChanges() above

     //... prior code ...
     // assume that 4 is the log id of the record just inserted
     // and 1000 is the fk_ref intended to be inserted
     LogTable _new = _me.LogTable.where(p=>p.LogID == 4).FirstOrDefault();
     // when I inspect _new the fk_ref post save changes the value is 1000
     _new.fk_ref = 999;
     _me.SaveChanges();

Retrieving the record from the db again fk_ref is still null

1 Answers

Found the Answer I have no idea how to categorize this but the answer was in a scope not included in the original question. My thanks to all who responded as you pushed me to look under different rocks - sometimes that is all you need. additional scope for question This project is part of an enterprise wide management tool delivered via a One-click interface. Each of the 20 or so different business surfaces has their own management project which may or may not be written within the IT development group. (Democritization and all that). The subordinate projects are user control DLLs that are then distributed along with the main shell. The entire solution gets data from several servers and more than a hundred DBs. The connection strings are managed through main shell. What I am currently working on is a project that has a number shared components and controls including an enhanced logger. (log4j and all related services are outlawed here). I was developing a new control for shared TimeKeeping that uses the shared controls project. More graphically it looks like this:

view of application references

  • Timekeeping had a reference to the Shared Controls project which had a EF object that connected to the DB that had the Log Table.
  • Project 1 had an EF object that connected to the DB that had the Log Table
  • The Shared Controls EF object was up to date. (the fk_ref field was added some time back)
  • Project 1 has been around a while (longer than the shared controls) and it's EF object was out of date.
  • Even though Timekeeping did not have a reference to Project 1 when the EF object in the Shared Controls was writing it used the definition Project 1.
  • Oddly enough, on a read the Shared controls retrieved all the fields

How I "proved" it

  • Created a mock up of the original application (WPF)

  • Added a user control project with EF connecting to a DB

  • used the control to write data to the DB

  • Closed out of VS

  • Used SSMS to modify the table

  • Opened VS added a new project with an EF project that connects to the same table

  • Added a third project that used a class in the second to write to the table referenced by the first and second.

  • any attempt to insert from the third project wrote a NULL into the added field

  • updated Model form Database in the first control project - checked to make sure the new field was there

  • Attempted to insert from the third project and all fields were inserted.

This seems odd to me but heck with all VS and MS have done for me who can complain. Off to make up for lost time. Believe it or not, I am more than a little happy I figured it out with all your help. Maybe this experience will help someone else.

Related