【问题标题】:Entity Framework throwing Null entry error at Saving, C#实体框架在保存时抛出空输入错误,C#
【发布时间】:2016-12-15 12:36:51
【问题描述】:

我正在研究 Entity Framework 6 和存储库设置以执行 crud 操作。我正在尝试在其中一个表中插入记录,并在空条目中出现错误,即使它不是。

{"Cannot insert the value NULL into column 'UI_ID', table 'Blackpool_BPM.dbo.COURSE_INSTANCE'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."}

与数据库的连接是正确的,因为我可以毫无问题地读取数据

在通用存储库中,在 Save() 之前正确获取数据

表结构

类模型

 [Table("COURSE_INSTANCE")]
public class BIZCourseInstanceEntity
{
    [Key]
    public int UI_ID { get; set; }

    public string UnitInstanceCode { get; set; }

    public string FESLongDescription { get; set; }

    public string FESShortDescription { get; set; }

    public string FullDescription { get; set; }

    public string OwningOrganisationCode { get; set; }

    public int? OwningOrganisationID { get; set; }

    public string TopicCode { get; set; }

    public string UnitCategory { get; set; }

    public string UnitCode { get; set; }

    public string FESQualificationType { get; set; }

    public int? SCHOOLS { get; set; }

    public int? MARKETING_GROUPS { get; set; }
}

存储库

 public class BIZCourseInstanceRepository : GenericRepository<BIZCourseInstanceEntity>
{
    public BIZCourseInstanceRepository() { }

    public BIZCourseInstanceRepository(DbContext dbContext)
        :base(dbContext)
    { }
}

工作单元类

  public class BIZ_UOF : IDisposable
{
    private BIZDbContext _BIZDbContextObject = new BIZDbContext();

    protected BIZCourseInstanceRepository _BIZCourseInstanceRepository;

 public BIZCourseInstanceRepository BIZCourseInstanceRepository
    {
        get
        {
            if (this._BIZCourseInstanceRepository == null)
            {
                this._BIZCourseInstanceRepository = new BIZCourseInstanceRepository(_BIZDbContextObject);
            }

            return _BIZCourseInstanceRepository;
        }
    }
    /////

   public void Save()
    {
        _BIZDbContextObject.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);

        _BIZDbContextObject.SaveChanges();
    }

    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                _BIZDbContextObject.Dispose();
            }
        }
        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

数据库上下文

public class BIZDbContext : BaseContext<BIZDbContext>
{
    public BIZDbContext() : base("_DbContext")
    { }

    public DbSet<BIZCourseInstanceEntity> BIZ_CourseInstance { get; set; }     
}

通用存储库 CRUD

 public void InsertEntity(TEntity obj)
    {
        _DbSet.Add(obj);
    }

在 Save() 处生成错误的函数类

  public void InsertCourseInstance()
    {
        BIZCourseInstanceEntity BIZCourseInstanceEntityObject = null;

        BIZCourseInstanceEntityObject = new BIZCourseInstanceEntity
        {
            UI_ID = 999999,
            UnitInstanceCode = "KZ999999",
            FESLongDescription = "LONG",
            FESShortDescription = "SHORT",
            FullDescription = "FULL",
            OwningOrganisationCode = "E",
            OwningOrganisationID = 155,
            TopicCode = "04.1",
            UnitCategory = "04",
            UnitCode = "HE-G", 
            FESQualificationType = null,
            SCHOOLS = 5,
            MARKETING_GROUPS = 44

        };

        using (var _uow = new BIZ_UOF())
        {
            _uow.BIZCourseInstanceRepository.InsertEntity(BIZCourseInstanceEntityObject);

            _uow.Save();
        }
    }

【问题讨论】:

  • 是的,它可以为空
  • 只是为了好玩,如果你排除了 UI_ID,只是不要将其设置为 999999,删除该行。
  • 哦,对不起,没读好。
  • 您在BIZDbContextBaseContextOnModelCreating 方法中是否有任何其他映射,例如Fluent Mapping,您指定UI_ID 应该是Identity 或@987654339 @ 类型?将其从生成的INSERT sql 语句中排除并解释异常的设置。
  • ^--- (继续) -- 我知道你想强制插入,但如果模型设置为根据上面的错误设置排除它并且数据库配置为不生成值,那么一旦您尝试从 EF 插入该表,就会发生异常。然后修复是更正模型映射并删除IdentityComptuted 标志。

标签: c# entity-framework-6 repository-pattern unit-of-work


【解决方案1】:

您需要告诉 Entity Framework 您的 ID 是一个身份字段。如果它没有在数据库中设置,那么你需要这样做。否则,您将需要查询下一个可用 ID,然后希望您不会与另一个尝试同时保存内容的请求发生冲突。

[Table("COURSE_INSTANCE")]
public class BIZCourseInstanceEntity
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UI_ID { get; set; }
    ...
}

如果您绝对必须在没有任何数据库生成的主键选项的情况下工作,您可以改用枚举的DatabaseGeneratedOption.None 值。应该避免这种情况以防止您的 PK 发生冲突,但该选项确实存在。

【讨论】:

  • 没有同样的错误,也不是自动生成的密钥,我正在向它发送值
  • 好吧,如果您使用相同的 ID 并将其强制为 INSERT,那么我可以看到抛出异常。也许他们看起来不够接近 SQL Server 返回的错误,因为这是一个相当边缘的情况。你真的应该让数据库设置 ID。
  • UI_ID 是由数据库自动生成的吗?我的意思是,它是否具有例如自动增量 1 的身份规范?
  • 在提供的内容中看不到,但作为桌上的PK,确实应该如此。我做了一个(显然)不正确的假设,但是我认为现在变成了 X-Y 问题。如果 OP 试图在 C# 代码中手动设置 PK,那么很快就会出现许多其他错误。
  • 我用 [DatabaseGenerated(DatabaseGeneratedOption.None)] 更改了键定义,它起作用了……非常感谢,另外投票!
【解决方案2】:

我找到了答案,问题出在我的数据库中,我需要提供主键,在我的情况下是 UI_ID,但在我的模型中我没有定义 DatabaseGeneredOption.None,因此抛出错误,感谢 Krillgar 指导我

这里是更新的模型

[Table("COURSE_INSTANCE")]
public class BIZCourseInstanceEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int UI_ID { get; set; }

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

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

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

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

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

    public int? OwningOrganisationID { get; set; }

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

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

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

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

    public int? SCHOOLS { get; set; }

    public int? MARKETING_GROUPS { get; set; }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多