Entity Framework 5: using the DatabaseGeneratedOption.Computed option

I have the first EF5 code project that uses the [DatabaseGenerated (DatabaseGeneratedOption.Computed)] attribute. This parameter overrides 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 use the default SQL construct to set [Name] if it is not installed.

In the code behind, I have a class defined as:

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

When I update an object in code, the default value overrides my new setting.

In the code, I have (pseudo):

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

Expected Result: Vehicle.Name = 'Update Vehicle Name'.

Actual result: 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 a value in the code, I want to use that value."

Thanks.

Steve

+6
source share
3 answers

Apparently not. This is not that smart :)

As you can already read, the Computed parameter simply tells EF not to update your column, since you yourself will calculate the value on the DB side. EF then simply returns the new calculated value from your database (which is "not set" in your case).

Your three main parameters are according to the EF source code documentation:

  • No - the database does not generate values.
  • Identifier. The database generates a value when inserting a row.
  • 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 user logic to be required, I am afraid that you will have to do it yourself. I would advise you to stop relying on the default restriction of the database and do everything in the first approach to the code. So you will have a code like this:

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

That way, when your Entity is created, it starts automatically with the expected default value. And subsequently, you can change just by changing the Name property.

Hope this helps!

+9
source

I tested this for hours to get a good answer, but no: EF cannot update models using an automatically generated identifier.

You have 3 options:

  • Adding another VehicleId model to the car.
  • Change the automatically generated identifier to be generated manually.
  • Setting a unique identifier for something else, and then the generated identifier in your model. In your vehicle class, this may be the Name property.

I suggest you option 3: Set up a unique identifier - Vehicle.Name (and you can add additional properties). Then: if the vehicle with a unique identifier does not exist, add a new car in db-context:

 //if there is no such a Vehicle in system, add it: if (vehicle.Name !=null && vehicle.Name != String.Empty && _dbContext.Where(v => v.Name == vehicle.Name).FirstOrDefault() == null) _dbContext.Add(vehicle); _dbContext.SaveChanges(); 
0
source

Actually there is a simple solution for this:

  • You need to leave the default constraint with the value in the script table creation, as of now:

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

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

And what is it: now the database will use the default value only if you do not specify any value in the code. Hope this helps.

0
source

Source: https://habr.com/ru/post/949257/


All Articles