41

I have a Date column in table which has default value or binding as getutcdate(). I want to use this in entity framework.On generating EDM I was able to find "Default Value " property at column level but I think it is for hardcoded value.

Please let me know how can I use default value specified in database.

johnnyRose
  • 7,310
  • 17
  • 40
  • 61

9 Answers9

9

Implementing the OnCreated event for the entity is the solution I have found. I had a Guid property that I wanted to be populated. By default it was being populated with all zeros (00000-0000-00000-etc). By adding the following to my partial class of the entity I was able to deal with the issue.

partial void OnCreated()
{
    Guid = Guid.NewGuid();
}
Heather
  • 2,602
  • 1
  • 24
  • 33
  • Does the entity raise this event automatically? Where do you wire the event handler? – Welton v3.62 Nov 03 '10 at 17:53
  • The event is wired automatically. – Heather Nov 18 '10 at 16:20
  • Are you sure this is for entity framework? The only documentation I can find for this is for Silverlight, and I can find no defining OnCreated partial method to implement in my EF entities. – Alex Jun 05 '14 at 12:35
  • That comment is a few years old and referring to and old version of EF. I would use a static factory method in a partial of the class to set defaults if you're using EF > 4. – Heather Jun 09 '14 at 22:58
4

StoreGeneratedPattern = "Computed" is not the same as a default value, because this property would be updated EVERY TIME with the default value in the database.. meaning it is impossible to update it manually.

4

You can set the StoreGeneratedPattern to Identity, in which case EF reads the value returned from the database after executing the INSERT statement. The problem with this approach is that the next time the XML mapping is generated, your change will be lost.

Another way to do it is to set the value yourself in your code to DateTime.UtcNow. You could set this in your entity's constructor (define a new constructor if necessary), or you could set it in your own event handler for your context's SavingChanges event (see How to: Execute Business Logic When Saving Changes (Entity Framework) for an example of handling the SavingChanges event).

mvr
  • 161
  • 3
4

A problem with setting StoreGeneratedPattern = "Computed" or "Identity" is that they do not allow the client to ever provide a value. Running into this issue on inserts but also for updates.

Seems like another option or two is needed for StoreGeneratedPattern so the database can at least see the user provided values but override it if need be. This would allow any existing DB insert or update triggers that update one field based on another field to work. For instance a DB trigger on an update might update the modified timestamp only if one is not provided and only if certain fields were updated.

Perhaps the column extended attributes feature in SQL Server could be used to set that field automatically during extraction so we don't end up editing XML files.

crokusek
  • 5,345
  • 3
  • 43
  • 61
  • 1
    For inserts into non-nullable fields, having a setting like "ComputedIfNull" would work. EF would not insert that field and then return whatever was committed into the field by the engine (due to column default, trigger, etc). – crokusek Jun 03 '16 at 23:37
1

There is another solution suggested in this post by using a partial class and a method in the constructor to set the values.

How to use the default Entity Framework and default date values

Community
  • 1
  • 1
NER1808
  • 1,829
  • 2
  • 33
  • 45
0

Here's a possible, but not pretty workaround -

Setting Computed on a column will make it read only, but will make the default value work. It's possible to have a real Computed column, say "LastChangedAt_computed" that either shows the value of "LastChangedAt_default" or "LastChangedAt_manual".

Now, the computed column shows the value of the default column, unless the manual column is not-null, in which case it is shown. In the model, the StoragePattern of the default column needs to be "Computed".

It's an ugly solution, but it should work.

johnnyRose
  • 7,310
  • 17
  • 40
  • 61
Asaf R
  • 6,880
  • 9
  • 47
  • 69
0

It is pretty simple to create a partial class for the entity model(s), similar to what you do for data annotations. Then I override the default constructor and set the default properties in the constructor. Works like a charm.

public partial class CallHistoryLog
{
    public CallHistoryLog() 
    {
        this.NumberFromId = -1L;
        this.NumberFromName = "NO NAME";
        this.NumberToId = -1L;
        this.NumberToName = "NO NAME";
        this.RouteId = -1L;
        this.Viewed = false;
        this.Deleted = false;
        this.DateCreated = DateTime.Now;
    }
}
Lorraine
  • 1,189
  • 14
  • 30
0

Hmm... if you are using EF6, this is actually a lot easier than you might think. Just open your model, right click on the column you want to set a default for, choose properties, and you will see a "DefaultValue" field. Just fill that out and save. It will set up the code for you.

The problem with some of the other solutions, it that while they may work initially, as soon as you rebuild the model, it will throw out any custom code you inserted into the machine-generated file.

So under the hood the UI works by adding an extra property to the edmx file:

<EntityType Name="Thingy">
  <Property Name="Iteration" Type="Int32" Nullable="false" **DefaultValue="1"** />

And by adding the necessary code to the constructor:

public Thingy()
{
  this.Iteration = 1;
Acorndog
  • 1
  • 1
0

Insert thats format:

    //class
    [Column("guid")]
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public string guid_ { get; set; }
    ...
    //end class

after the command yourContext.SaveChanges();

You can see return default data from database in your class model.

Good Look