Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework 5: Using DatabaseGeneratedOption.Computed option

I have an EF5 code first project that uses the [DatabaseGenerated(DatabaseGeneratedOption.Computed)] attribute.
This option is overriding my settings.

Consider this SQL table:

CREATE TABLE Vehicle (
  VehicleId  int identity(1,1) not null,
  Name varchar(100) not null default ('Not Set')
)

I am using the SQL default construct to set the [Name] is case it is not set.

In code behind, I have a class defined similar to:

public class Vehicle {
   ...

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public string ShoulderYN { get; set; }
}

When I update the entity in code, the value set in the default overrides my new setting.

In code, I have (pseudo):

vehicle.Name = 'Update Name of Vehicle';
_dbContext.Update(vehicle);
_dbContext.SaveChanges();

The expected result is Vehicle.Name = 'Update Name of Vehicle'.
The actual result is Vehicle.Name = 'Not Set'.

Is there a way in EF5 to say:
if Vehicle.Name is null/empty, use the value defined in the database? Otherwise, if I set the value in code, I want to use this value.

like image 463
Steve Avatar asked Jul 11 '13 18:07

Steve


2 Answers

Apparently, no there isn't. It's not that smart :)

As you may already read, Computed option just tells the EF not to update your column, because you will compute a value on the DB-side yourself. EF will then just return newly computed value from your database (which in your case is "Not Set").

Your basic three options are - as per EF Source code documentation:

  • None - The database does not generate values.
  • Identity - The database generates a value when a row is inserted.
  • Computed - The database generates a value when a row is inserted or updated.

https://github.com/aspnet/EntityFramework6/blob/527ae18fe23f7649712e9461de0c90ed67c3dca9/src/EntityFramework/DataAnnotations/Schema/DatabaseGeneratedOption.cs

Since you expect a little more custom logic to be done, I'm afraid you would have to do it yourself. I would suggest you stop relying on database default constraint and do everything in code first approach. This way you would have a code like that:

public class Vehicle
{
  public Vehicle()
  {
    this.Name = "Not set";
  }
  
  // Without 'Generated' attribute
  public string Name { get; set; }
}

This way, when your Entity is created, it automatically starts with expected default value. And can be later changed by simply modifying the Name property.

Hope it helps!

like image 187
tomalone Avatar answered Nov 11 '22 06:11

tomalone


Actually there is a simple solution for this:

  • You need to leave default constraint with value in table creation script as it is now:

    CREATE TABLE Vehicle (
      VehicleId  int identity(1,1) not null,
      Name varchar(100) not null default ('Not Set')
    )
    
  • Just remove DatabaseGenerated attribute from property in class definition:

    public class Vehicle {
       ...
    
       [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
       public string ShoulderYN { get; set; }
    }
    

And that's it: now database will use default value only if you do not specify some value in code. Hope this helps.

like image 1
Grengas Avatar answered Nov 11 '22 04:11

Grengas