Entity Framework Extensions ForceValueGeneratedStrategy Option

Description

In EF Core, you can set a value to a property even if you have set a default value in the database with .HasDefaultValue(100);

  • A value is set: The column will be included in the INSERT statement, and the value will be inserted in the database.
  • No value is set: The property will be ignored and won't be part of the INSERT statement (so the default value will be inserted).

Using SaveChanges or BulkSaveChanges, both follow this behavior and handle this scenario correctly.

For performance optimization, other bulk methods like EF Core Bulk Insert don't have this behavior. The default behavior always ignore the property value and lets the default value be inserted, even if a value has been specified in your entity.

For example, if the TokenLimit has a default value of 100, both customers will have the value 100 inserted, even if a TokenLimit was specified for the ZZZ Projects customer.

var customers = new List<Customer>();

customers.Add(new Customer() { Name = "ZZZ Projects", TokenLimit = 200 });
customers.Add(new Customer() { Name = "Jonathan Magnan"});

context.BulkInsert(customers);
CustomerID Name TokenLimit
1 ZZZ Projects 100
2 Jonathan Magnan 100

Try it

However, you can change this default behavior by using the ForceValueGeneratedStrategy = ValueGeneratedStrategyType.OnAddOrUpdate, which will now always insert the property value (even if none was specified). In this scenario, 200 will be inserted for the ZZZ Projects customer, and 0 will be inserted for Jonathan Magnan (The TokenLimit property had the value 0 for him).

var customers = new List<Customer>();

customers.Add(new Customer() { Name = "ZZZ Projects", TokenLimit = 200 });
customers.Add(new Customer() { Name = "Jonathan Magnan"});

context.BulkInsert(customers, options => {
	options.ForceValueGeneratedStrategy = ValueGeneratedStrategyType.OnAddOrUpdate;
});
CustomerID Name TokenLimit
1 ZZZ Projects 200
2 Jonathan Magnan 0

Try it

Mixed Scenario

We support either always ignoring the property value or always using it.

Currently, we don't support a mix scenario where you set a value for some entities and not for others. If you come across this case, you'll need to split it into two separate bulk inserts:

context.BulkInsert(customers.Where(x => x.TokenLimit == 0));
context.BulkInsert(customers.Where(x => x.TokenLimit != 0), options => {
	options.ForceValueGeneratedStrategy = ValueGeneratedStrategyType.OnAddOrUpdate;
});

Last updated: 2023-10-11
Author:


Contents