【问题标题】:Can not insert row to database because of relationship problems由于关系问题,无法将行插入数据库
【发布时间】:2013-11-28 15:18:22
【问题描述】:

首先,我使用的是 ASP.NET MVC 4 和 Entity Framework 5。这是我在 MVC 中的第一个项目。

我正在尝试在我的 WorkLogs 表中插入一行。我已经使用代码优先方法创建了我的数据库。

这是我的 WorkLogs 模型(由于我创建了数据库,我没有对我的模型进行任何更改):

public class WorkLogs
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int WorkLogId { get; set; }
    [Required]
    public int Time { get; set; }
    [Required]
    public DateTime Date { get; set; }
    [Required]
    public DateTime CreatedDate { get; set; }
    [Required]
    public bool IsSent { get; set; }

    public virtual Users User { get; set; }
    public virtual Works Work { get; set; }
}

此模型已在数据库中创建此表:

这些是关系(对我来说似乎是正确的):

我正在尝试在我的控制器中使用此代码添加一个新行:

WorkLogs log = new WorkLogs()
{
    Time = iTime,
    Date = beginWeek.AddDays(i),
    CreatedDate = DateTime.Now,
    User = userObj, 
    Work = workObj, 
    IsSent = true
};

_db.WorkLogs.Add(log);
_db.SaveChanges();

当我运行它时,它会在 _db.SaveChanges(); 中引发异常;行。

保存不为其关系公开外键属性的实体时发生错误。 EntityEntries 属性将返回 null,因为无法将单个实体标识为异常源。通过在实体类型中公开外键属性,可以更轻松地处理保存时的异常。有关详细信息,请参阅 InnerException。

当我看到此异常时,我了解关系存在问题。而且我也知道我正在尝试将对象插入到需要整数的列中。但我不明白它创建了 User_UserId 和 Work_WorkId 列并为它们提供了 int 数据类型。但在控制器中,它需要一个用户对象。

我的模型,控制器可能全错了。但正如我所说,我是 EF 和 MVC 的新手。

我应该做哪些更改才能将工作日志插入我的数据库?

我希望我说清楚了。

任何帮助将不胜感激。

【问题讨论】:

  • 我推荐这两篇文章:使用缺少的外键msdn.microsoft.com/en-us/magazine/hh708747.aspx 和为什么实体框架将现有对象重新插入我的数据库? msdn.microsoft.com/en-us/magazine/dn166926.aspx。另外,我们还需要查看WorksUsers 类,以及InnerException 中的错误消息
  • 一些旁白——你不需要 [Required] 在不可为空的类型上标记,DatabaseGenerated(DatabaseGeneratedOption.Identity) 是多余的,因为它是整数键的默认值,并且实体类的正常命名约定是单数.当您遵循该约定时,EF 将假定 WorkLogIdWorkLog 类的 [Key] 并且该属性也变得多余。而且您的数据库表会自动复数。
  • 这里是:作品:i.imgur.com/nvXREfc.png 和用户:i.imgur.com/oRLLN8d.png 我做了一些 Réda Mattar 所说的更改。现在是我内心的前任。是:i.imgur.com/HPVCyNB.png
  • 在我忘记之前,感谢您的文章。立即阅读。

标签: c# asp.net-mvc entity-framework asp.net-mvc-4


【解决方案1】:

内部异常是SqlException。 “The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value”。如果您搜索该消息,您很快就会找到原因:

您已将WorkLogs 上的CreatedDateDate 设置为合理的值,因此在Works 的实例中,罪魁祸首可能是CreatedDate 和/或UpdatedDate

如果您没有设置它们,那么它们的值将是 .NET 的默认值 - DateTime.MinValue - 0001 年。尝试将其插入到数据库中会出现溢出,因为在 Sql Server 中,最小值是 @987654330 @ - 1753 年。

我建议您在构造函数中将CreatedDate 的值设置为DateTime.Now,并将UpdatedDate 的类型更改为可空的DateTime(默认为空而不是DateTime.Min

【讨论】:

  • 是的!有效。非常非常感谢你。日期是 0001 年。现在它完美地写入 db。我必须提高自己阅读错误的能力。
【解决方案2】:

您可以使用ForeignKeyAttribute 将导航属性与外键链接:

public class WorkLogs
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int WorkLogId { get; set; }

    [Required]
    public int Time { get; set; }

    [Required]
    public DateTime Date { get; set; }

    [Required]
    public DateTime CreatedDate { get; set; }

    [Required]
    public bool IsSent { get; set; }

    public int Users_UserId { get; set; }

    public int Works_WorkdId { get; set; }

    [ForeignKey("Users_UserId")]
    public virtual Users User { get; set; }

    [ForeignKey("Works_WorkdId")]
    public virtual Works Work { get; set; }
}

【讨论】:

  • 不确定这是一个好步骤还是坏步骤,但它给出了:更新条目时出错。有关详细信息,请参阅内部异常。
  • 那么内部异常呢?
【解决方案3】:

请务必注意,Entity Framework支持以下无符号数据类型:

How to use unsigned int / long types with Entity Framework?

http://tektutorialshub.com/code-first-conventions-in-entity-framework/

如果您偶然将任何主键设置为 UNSIGNED DATATYPE,您不仅会遇到此特定错误,还会遇到与模型上的表关系相关的许多其他错误。

【讨论】:

    猜你喜欢
    • 2011-01-24
    • 2010-12-14
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    相关资源
    最近更新 更多