13

In my SQL Server database schema I have a data table with a date field that contains a default value of

CONVERT(VARCHAR(10), GETDATE(), 111)

which is ideal for automatically inserting the date into the new record when manually entering records in to the database.

The problem I have is that when using the Entity Framework and mapping the Date field, that the Entity Framework inserts a default value of DateTime.Min when the entity is instantiated.

I cannot map the Date field to a nullable DateTime, i.e. DateTime?, nor am I able to use either CONVERT or DateTime.Now.Today in the default value of the Entity Designer as it only accepts hard-coded constant values.

I can of course explicitly set the DateTime field in C# whenever the object is created, either explicitly in code, in the constructor of a partial class, or even during the saving changes event.

Are there any other ways of achieving what I want where the default value calculation stored in the database table is actually used instead?

Justin
  • 490
  • 1
  • 3
  • 11
  • You could try setting the field as auto-generated. I've never tried this and am not sure how well it would work. – Craig Stuntz Oct 22 '09 at 19:23
  • I looked around in the EDM Designer and did not see any options, menu items or properties that I could describe as offering that. Where would I find "set field as auto-generated" within the designer? I assume you are referring to the designer, and not something in SQL Server. Or perhaps you are referring to "computed column specification?" – Justin Oct 22 '09 at 22:03
  • 1
    http://msdn.microsoft.com/en-us/library/dd296755.aspx – Craig Stuntz Oct 26 '09 at 12:58
  • Craig, thanks for that link. An almost perfect solution. It works, but it gets over-written when updating the EDMX using the designer tool, as pointed out in the linked article. – Justin Oct 28 '09 at 23:57

8 Answers8

13

Create a partial class for your EntityObject, add a default constructor, and set default values in it.

    public partial class YourDBObject
    {
          public YourDBObject()
          {
               this._DateField = DateTime.Now;
          }
    }
Chase
  • 139
  • 1
  • 3
  • Exactly what I needed (though not for this question)! :D – nathanchere Apr 07 '10 at 06:28
  • 3
    Thanks. This works, although it confused me at first because the constructor also gets called when existing objects are fetched from the database - however in those cases the `DateTime.Now` gets overwritten with the database values after construction. – codeulike Oct 05 '10 at 10:32
5

You can use a database trigger, which, on insertion, checks if the inserted value is DateTime.MinValue (01.01.0001) and replaces it with the calculated value you desire. This MSDN article describes how to create a trigger.

A little "flaw": with this solution you would have to store the new object to the database and read it back afterwards to update your object with the calculated value.

andyp
  • 6,229
  • 3
  • 38
  • 55
  • 3
    Good point. That would work too. But it just feels like I am wielding a sledgehammer to crack a walnut. – Justin Oct 22 '09 at 22:00
3

This is really unfortunate. The answers referencing StoreGeneratedPattern are not a true solution, that doesn't allow you to ever set the value.

All the team would have to do is something like this:

    [Required]
    [DefaultValue] // suggested attribute, whatever you want to call it
    public DateTime Created { get; set; }

If a field is marked DefaultValue, then at EF's SQL generation time, properties with this attribute get checked if field == default(DateTime), if so, then simply omit that column from the generated code.

Nicholas Petersen
  • 9,104
  • 7
  • 59
  • 69
2

Just happened to cross through this issue. Entity Framework do not support default values on its own. You need to set the property StoreGeneratedPattern = Computed on the column in the Edmx file entity. The default value what you set in the Database will then precedence on what EF sets by default i.e. DateTime.Min

1

I just ran into this - I worked around it by setting the date (the field I needed auto generated) in the constructor of the Entity using a partial method. Whether this is Ideal or whether it works in all cases is yet to be seen, but it has fixed my problem so far.

Adam Tolley
  • 925
  • 1
  • 12
  • 22
  • 1
    This is the solution I finally chose. It seems a bit of a kludge, but it works flawlessly. A shame that such an oversight is present in the EF. – Justin Oct 28 '09 at 23:54
  • Glad to have helped, Lets hope EF4 fixes this bit of pain. If you think this is the best solution your likely to find please mark it as the answer (or at least upvote it) so I can get some credit - I'm trying to build at least enough rep to use this site a little more actively. Thanks! – Adam Tolley Nov 02 '09 at 15:15
  • 1
    I would do that, but it requires 15 reputation. Sorry. – Justin Nov 06 '09 at 02:45
  • 3
    If you do this won't the date being stored be the one where the EF context code is running (potentially the client), rather the database server. Meaning a user could 'fake' dates by changing the time on their PC. – AndyM Apr 30 '10 at 11:37
  • Setting the date in the constructor will break n-tier apps using canonical data models over WCF –  Nov 11 '13 at 04:29
  • I would really love to see some example code in this answer. I know this is what I need to but I can't work out the correct code. – Nick.Mc Feb 05 '17 at 05:24
  • Hi Nick, this was probably my first SO answer, and I don't remember anything about it. By the looks of it, http://stackoverflow.com/a/2042838/174965 is what you want, and inline with what I described above. – Adam Tolley Feb 06 '17 at 23:24
1

I think the answer provided by lazyberezovsky on another SO question is the straight forward solution to this problem Entity Framework and Default Date

Community
  • 1
  • 1
VahidNaderi
  • 2,448
  • 1
  • 23
  • 35
1

I had a similar problem using RIA Services with the Entity Framework. I was not able to set the value in the default constructor on the client side because the entity classes that are generated there already have an empty default constructor.

The solution that I used was to implement the OnCreated partial method for the entity on the client by setting the required default value.

Scott Munro
  • 13,369
  • 3
  • 74
  • 80
0

The date field can be mapped to DateTime? only if the column is nullable in the database.

kubal5003
  • 7,186
  • 8
  • 52
  • 90
  • But if the column is nullable, then logic dictates you cannot have a "default value." And this is the behaviour as exhibited by the SQL server. – Justin Oct 28 '09 at 23:59