为什么EF种子方法在DateTime上插入Null?

时间:2018-07-26 16:54:25

标签: c# entity-framework entity-framework-6

我正在尝试在我的Code-First EF 6项目中实现AddOrUpdate方法。我收到一条错误消息,指出属性AdmCreatedDate中不允许使用null。错误下方:

  

运行种子方法。 System.Data.Entity.Infrastructure.DbUpdateException:更新条目时发生错误。有关详细信息,请参见内部异常。 ---> System.Data.Entity.Core.UpdateException:更新条目时发生错误。有关详细信息,请参见内部异常。 ---> System.Data.SqlClient.SqlException:无法将值NULL插入表“ TPPX.dbo.ExemptionCalculationConfig”的“ AdmCreatedDate”列中;列不允许为空。 INSERT失败。该声明已终止。

这是我的代码... 我有一个名为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; }
    }
}

如您所见,该类继承了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; }

    }
}

然后我的Migrations文件夹中有Configuration.cs文件: 我尝试添加要保存在数据库中的对象列表以及仅单个实例。另外,我已经明确尝试创建一个名为seedCreatedDate的DateTime对象,使用DateTime.Today甚至DateTime.ParseExact()作为AdmCreatedDate的值,但没有运气:(

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();
        }
    }
}

我看到其他人没有明确地说出他们的主键不应该是Identity列时也有同样的错误,但这不是我的情况。我想念什么?

1 个答案:

答案 0 :(得分:0)

好的,伙计们。

我知道了(有点)。

感谢IvanStoev指出了计算属性和身份属性。

我的DbContext中确实包含以下行:

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

由于某种原因,当Seed方法尝试运行并且对象具有计算属性时,EF不喜欢它。我与项目负责人进行了交谈,并说服她从EF中删除了该计算值(因为它甚至不影响数据库。EF仅在代码上处理它。在SQL Server中检查数据库后,我注意到该列实际上未设置为老实说,我不喜欢这样,因为如果将来我们决定不使用EF,那么计算的属性将会丢失。

因此,总而言之,您无法在Seed()方法中使用具有计算属性的模型

现在,我们处理实际数据库中的计算列。

很高兴知道,我在网上找不到,这就是EF为何采用这种方式的原因。如果有人知道,请告诉我。

希望这会有所帮助:)