未使用数据库默认值,生成错误

时间:2011-08-17 19:16:40

标签: sql-server asp.net-mvc-3

我正在使用ASP.Net MVC 3和Code First以及SQl Server CE 4.我有一个名为EntryDate的属性(具有匹配的数据库列)。我已将数据库设置为默认值GETDATE()。

如果我通过输入将EntryDate保留为NULL的记录来手动编辑数据库,则默认工作并存储当前日期/时间。但是如果我通过从我的控制器在我的上下文中尝试SaveChanges()来做同样的事情,模型对象没有EntryDate属性的值,我得到以下错误:

“该列不能包含空值。[Column name = EntryDate,Table name = ActionItems]”

如果我在EntryDate列中更改数据库模式以允许空值,则默认规则不会触发,我最终会存储NULL。

任何指导都将受到赞赏..

更新:为了清楚起见,我可以在调用SaveChanges()之前在POST操作方法中轻松设置属性值:

    [HttpPost]
    public ActionResult Create(ActionItem actionItem)
    {
        if (ModelState.IsValid)
        {
            actionItem.EntryDate = DateTime.Now;
            db.ActionItems.Add(actionItem);
            db.SaveChanges();
            return RedirectToAction("Index");  
        }

我更愿意在数据库级别设置它。我的问题是:

  1. 为什么它不像我期望的那样自动工作?
  2. 是否有更简单的方法(即DataAnnotation)?
  3. 我是新手,所以我想也许对我所发生的事情有一些根本的误解。

    更新2:

    好吧,我很难过这种行为。上面的代码是我能让它工作的唯一方法,所以我想我会坚持下去。我最近的尝试是提供[Bind]注释,但它没有改变结果。 e.g。

    [HttpPost]
    public ActionResult Create([Bind(exclude = "EntryDate")] ActionItem actionItem)
    

    我可以针对数据库本身运行SQL查询,它提供了应该的默认值(我已经使用SQLExpress进行了测试,看它是否是数据库行为,但我猜不是)。但我似乎无法在不包含EntryDate = null的情况下创建EF,或者如果我使用datetime而不是datetime,则无法创建.minValue?

    有趣的是,我正在以与Id字段相同的方式处理字段,db显然提供了这个字段。我只是不明白。

    我想我有它的工作,但我想更好地理解这个机制。如果有人能够对此有所了解那就太棒了......

    由于

3 个答案:

答案 0 :(得分:4)

显然,您要向该字段发送空值。不要在插入中包含该字段。

答案 1 :(得分:0)

看起来你应该使用StoreGeneratedPattern枚举并用它来装饰你的映射。 This bug report显示他们刚刚发布了针对EF4的热修复解决方案,无法将其正确保存到edmx文件中。

答案 2 :(得分:0)

我知道它已经有一段时间,但对于其他人来说,这是一个领先者。

由于您从代码开始,您可以简单地将您的属性定义为Nullable,

例如: Nullable<bool> Active {get; set;}

然后,不要将它包含在HttpPost中:

public ActionResult Create([Bind(Include = "Name")] User user)  (或&#34;排除&#34;它与您一样,但您应该更喜欢[Bind(Include = "Prop1,Prop2...")]以防止过度投放。)

由于属性被定义为可空,因此它不会生成异常,但是,这确实会导致发送空值......

由于您使用的是代码优先,因此提供模型定义可能会帮助其他人提供更好的答案。 ; - )

对于这种情况,您可以考虑使用ViewModel,只通过ViewModel传递和查看您绝对需要的数据。

但是,假设您有一个这样的基类:

public partial class myClass
{
    public string Name {get; set;}
    public bool Valid {get; set;}
}

我发现定义默认值的最简单方法就是重新定义默认构造函数,如下所示:

public partial class myClass
{
    public myClass()
    {
        this.Valid = true;
    }

    public string Name {get; set;}
    public bool Valid {get; set;}
}

无需更改数据库默认值。 ; - )

如果您正在使用Model-First,它实际上更简单(只需更新模型,它就会将类支持回来)。

我还没有尝试使用Database-First,但它应该像MF一样简单。