c# - 为什么 EF Seed 方法在 DateTime 上插入 Null?
问题描述
我正在尝试在我的 Code-First EF 6 项目中实现 AddOrUpdate 方法。我收到一条错误消息,指出属性 AdmCreatedDate 中不允许使用空值。错误下方:
运行种子方法。System.Data.Entity.Infrastructure.DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。---> System.Data.Entity.Core.UpdateException:更新条目时出错。有关详细信息,请参阅内部异常。---> System.Data.SqlClient.SqlException:无法将值 NULL 插入到列“AdmCreatedDate”、表“TPPX.dbo.ExemptionCalculationConfig”中;列不允许空值。插入失败。该语句已终止。
这是我的代码...我有一个名为 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();
}
}
}
当其他人没有明确说他们的主键不应该是标识列时,我已经看到其他人也有同样的错误,但这不是我的情况。我错过了什么?
解决方案
好吧,伙计们。
我想通了(有点)。
感谢 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 会以这种方式运行。如果有人知道,请告诉我。
希望这可以帮助 :)
推荐阅读
- bash - Bash 配置文件变量
- swift - 想在swift中创建一个像google这样的搜索栏
- git - Git 损坏“无法读取 [sha]”但 git fsck 没有报告错误
- arrays - EXTjs 将 3 个值更改为单个数组
- ios - iOS 上的 Xamarin Forms 反向地理定位
- android - 拍照 > 保存图片 > 上传到 api > 删除像回收站这样的作品 >
- git - 更新子模块 URL
- python - 在“等待”时处理循环的下一次迭代
- mysql - 计算单个 SQL 表中两列的不同日期
- python - Python Pandas - 如何在具有不同级别数的索引上加入 DataFrames?