我正在使用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");
}
我更愿意在数据库级别设置它。我的问题是:
我是新手,所以我想也许对我所发生的事情有一些根本的误解。
更新2:
好吧,我很难过这种行为。上面的代码是我能让它工作的唯一方法,所以我想我会坚持下去。我最近的尝试是提供[Bind]注释,但它没有改变结果。 e.g。
[HttpPost]
public ActionResult Create([Bind(exclude = "EntryDate")] ActionItem actionItem)
我可以针对数据库本身运行SQL查询,它提供了应该的默认值(我已经使用SQLExpress进行了测试,看它是否是数据库行为,但我猜不是)。但我似乎无法在不包含EntryDate = null的情况下创建EF,或者如果我使用datetime而不是datetime,则无法创建.minValue?
有趣的是,我正在以与Id字段相同的方式处理字段,db显然提供了这个字段。我只是不明白。
我想我有它的工作,但我想更好地理解这个机制。如果有人能够对此有所了解那就太棒了......
由于
答案 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一样简单。