【发布时间】:2018-07-28 04:55:29
【问题描述】:
我正在尝试在我的 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();
}
}
}
我看到其他人在没有明确说他们的主键不应该是标识列时也有同样的错误,但我的情况不是这样。我错过了什么?
【问题讨论】:
-
将
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]属性添加到 AdmCreatedDate 属性。数据库中的该列可能应该使用默认的 GETDATE() 或 GETUTCDATE() 创建,因此数据库生成值,而不是应用程序。 -
看起来
AdmCreatedDate已通过 fluent API 配置为DatabaseGeneratedOption.Identity,在这种情况下,EF 在执行INSERT时不会发送该值。但同时数据库表列没有设置DEFAULT,所以异常。 -
@RobertMcKee 恕我直言,异常消息与您所说的相反。
-
@RobertMcKee 查看模型中的属性类型 - 它是
DateTime(不可为空),因此您无法显式尝试插入空值。只有 EF 可以做到这一点,当属性被标记为身份或计算时就会发生这种情况。 -
感谢大家花时间阅读并提供反馈,感谢@IvanStoev 对计算属性的评论,我已经解决了问题。如果您回答为什么我不能使用 fluent API 计算属性并使用种子方法,我会给您正确的答案。请记住,我也尝试不给 AdmCreatedDate 赋值,但种子方法仍然失败。了解为什么会发生这种情况会很棒:)
标签: c# entity-framework entity-framework-6