Why does EF Seed Method Insert Null on DateTime?

c# entity-framework entity-framework-6

Question

I am trying to implement the AddOrUpdate method in my Code-First EF 6 project. I get an error saying that nulls are not allowed in the property AdmCreatedDate. Below the error:

Running Seed method. 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. ---> System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'AdmCreatedDate', table 'TPPX.dbo.ExemptionCalculationConfig'; column does not allow nulls. INSERT fails. The statement has been terminated.

Here is my code... I have a model called ExemptionCalculationConfig:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TPPX.Domain.ExemptionModels.Entities.Lookups;

namespace TPPX.Domain.ExemptionModels
{
    [Table("ExemptionCalculationConfig")]
    public class ExemptionCalculationConfig : TPPXBaseEntity
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int Priority { get; set; }

        [ForeignKey("ExemptionApplyLevel")]
        public string ApplyAtLevelCode { get; set; }

        public virtual ExemptionApplyLevel ExemptionApplyLevel { get; set; }

        [ForeignKey("ExemptionApplyType")]
        public string ApplyByValueOrPercentageCode { get; set; }

        public virtual ExemptionApplyType ExemptionApplyType { get; set; }
        public bool IsProratable { get; set; }
    }
}

As you can see this class inherits TPPXBaseEntity:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;

namespace TPPX.Domain
{
    public class TPPXBaseEntity
    {
        [DefaultValue(true)]
        public bool IsActive { get; set; }

        public DateTime  AdmCreatedDate { get; set; }

        [StringLength(50)]
        public string AdmCreatedUser { get; set; }

        [StringLength(255)]
        public string AdmCreatedUserFullName { get; set; }
        public DateTime? AdmModifiedDate { get; set; }

        [StringLength(50)]
        public string AdmModifiedUser { get; set; }

        [StringLength(255)]
        public string AdmModifiedUserFullName { get; set; }

    }
}

Then I have my Configuration.cs file in my Migrations folder: I have tried adding a list of objects to save in the DB as well as just a single instance. Also, I have explicitly tried creating a DateTime Object called seedCreatedDate, used DateTime.Today and even DateTime.ParseExact() as values for AdmCreatedDate, but no luck :(

using System.Collections.Generic;
using System.Web;
using PA.Web.Configuration.WebConfigurationManager;
using TPPX.Domain.ExemptionModels;
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;

namespace TPPX.DAL.Migrations.TPPXDBContext
{


    internal sealed class Configuration : DbMigrationsConfiguration<TPPX.DAL.DBContexts.TPPXDBContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
            MigrationsDirectory = @"Migrations\TPPXDBContext";
        }

        protected override void Seed(TPPX.DAL.DBContexts.TPPXDBContext context)
        {
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
            //  to avoid creating duplicate seed data.
            //var seedCreatedDate = new DateTime(2018, 07, 26);

            //var exemptionCalculationConfigs = new List<ExemptionCalculationConfig>
            //{
            //    new ExemptionCalculationConfig
            //    {
            //        AdmCreatedDate = DateTime.Today,
            //        AdmCreatedUser = "carcruz",
            //        AdmCreatedUserFullName = "Cruz, Carlos (PA)",
            //        Priority = 1,
            //        IsProratable = false,
            //        ApplyAtLevelCode = "A",
            //        ApplyByValueOrPercentageCode = "P",
            //        IsActive = true
            //    },
            //    new ExemptionCalculationConfig
            //    {
            //        AdmCreatedDate = DateTime.Today,
            //        AdmCreatedUser = "carcruz",
            //        AdmCreatedUserFullName = "Cruz, Carlos (PA)",
            //        Priority = 2,
            //        IsProratable = false,
            //        ApplyAtLevelCode = "V",
            //        ApplyByValueOrPercentageCode = "V",
            //        IsActive = true
            //    }
            //};

            //exemptionCalculationConfigs.ForEach(
            //    x => context.ExemptionCalculationConfigs.AddOrUpdate(e => e.Priority, x));

            context.ExemptionCalculationConfigs.AddOrUpdate(
                e => e.Priority,
                new ExemptionCalculationConfig
                {
                    AdmCreatedDate = DateTime.Now,
                    AdmCreatedUser = "carcruz",
                    AdmCreatedUserFullName = "Cruz, Carlos (PA)",
                    Priority = 1,
                    IsProratable = false,
                    ApplyAtLevelCode = "A",
                    ApplyByValueOrPercentageCode = "P",
                    IsActive = true,
                    AdmModifiedDate = null,
                    AdmModifiedUser = null,
                    AdmModifiedUserFullName = null
                });
            context.SaveChanges();
        }
    }
}

I have seen others have this same error when they do not explicitly say their primary key should not be an identity column, but it is not my case. What am I missing?

1
1
7/26/2018 5:07:13 PM

Accepted Answer

Alright, guys.

I figure it out (kinda).

Thanks to IvanStoev who pointed out computed and identity properties.

I did have the following line in my DbContext:

modelBuilder.Properties<DateTime>().Where(x => x.Name == "AdmCreatedDate")
.Configure(c => c.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed));

For some reason, EF does not like it when the Seed method tries to run and the object has a computed property. I spoke to the project lead and convinced her to take that computed off of EF (since it does not even affect the DB. EF handles it on the code only. After checking the DB in SQL Server I noticed the column is not actually set as computed) Honestly, I don't like this because if in the future we decide to not use EF, the computed properties will be lost.

So, in summary, you can't have models with computed properties in the Seed() method

Now, we handle the computed column in the actual DB.

What would be nice to know, which I was not able to find on the web is why EF behaves this way. If anyone knows, please do let me know.

Hope this helps :)

0
7/27/2018 8:55:29 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow