Database default value not being used, generates error
I'm using ASP.Net MVC 3 with Code First and SQl Server CE 4. I have a property (with matching database column) called EntryDate. I've set the database to default to a value of GETDATE().
If I manually edit the database by entering a record leaving EntryDate as NULL, the default works and the current date/time is stored. But if I do the same thing by trying SaveChanges() on my context from my controller, with the model object having no value for the EntryDate property, I get the following error:
"The column cannot contain null values. [ Column name = EntryDate,Table name = ActionItems ]"
If I change the database schema to allow for nulls in the EntryDate column, the default rule doesn't fire and I end up with NULL being stored.
Any guidance would be appreciated..
Update: just to be clear, I can easily enough set the property value in the POST action method prior to calling SaveChanges():
[HttpPost]
public ActionResult Create(ActionItem actionItem)
{
if (ModelState.IsValid)
{
actionItem.EntryDate = DateTime.Now;
db.ActionItems.Add(actionItem);
db.SaveChanges();
return RedirectToAction("Index");
}
I would just prefer to set this at the database level. My questions are:
- Why doesn't it work automatically like the way I'd expect it to?
- Is there an easier way (i.e. a DataAnnotation)?
I'm new to this, so I think maybe there's some fundamental misunderstanding of what's happening on my part.
Update 2:
Well I'm stumped at this behaviour. The code above is the only way I can get it to work so I guess I'll stick with that. My most recent try was supplying a [Bind] annotation but it didn't change the result. e.g.
[HttpPost]
public ActionResult Create([Bind(exclude = "EntryDate")] ActionItem actionItem)
I can run a SQL query against the database itself and it supplies the default value as it should (I've tested with SQLExpress to see if it's a database behaviour but I guess not). But I can't seem to get EF to create the query without including EntryDate = null, or as .minValue if I use datetime instead of datetime?
The funny thing is I'm开发者_开发技巧 handling the field the same way as the Id field, which the db supplies itself obviously. I just don't get it.
I guess I have it working but I'd like to understand the mechanism better. If anyone can shed some light on this that'd be great..
Thanks
Apparently you are sending a null value to the field. Do not include the field in your insert.
It seems like you should use the StoreGeneratedPattern enumeration and use it to decorate you mappings. This bug report shows they just released a hot fix for EF4 to resolve it not saving correctly into the edmx files.
I know it's been a while but for others looking into this, here's a lead.
Since you're starting from code, you could simply define your property as Nullable,
ex:
Nullable<bool> Active {get; set;}
Then, not include it in the HttpPost like this:
public ActionResult Create([Bind(Include = "Name")] User user)
(Or "Exclude" it like you did, but you should prefer [Bind(Include = "Prop1,Prop2...")]
in order to protect from overposting.)
Since the property is defined as nullable, it won't generate an exception, however, this will indeed result in sending a null value...
Since you're using code-first, providing the model definition would have probably helped others to give a better answer by the way. ;-)
For this kind of scenario, you may consider instead a ViewModel and passing to and from the View only the data you absolutely need through the ViewModel.
But let's assume you have a base class like this :
public partial class myClass
{
public string Name {get; set;}
public bool Valid {get; set;}
}
The most simple way I've found to define a default value is simply to redefine the default constructor like this :
public partial class myClass
{
public myClass()
{
this.Valid = true;
}
public string Name {get; set;}
public bool Valid {get; set;}
}
No need to change the database default values. ;-)
If you're working with Model-First, it's actually simpler (just update the model and it will scaffold the classes back).
I haven't tried with Database-First, but it should be as simple as MF.
精彩评论