EntityFramework-Extensions icon indicating copy to clipboard operation
EntityFramework-Extensions copied to clipboard

BulkInsert Using Default values

Open talkwaqar opened this issue 6 years ago • 34 comments

We are using database first approach with entity framework core. We found one bug that if database column has default value and when we do bulk insert library do not save values instead use database column default values.

talkwaqar avatar Dec 14 '18 11:12 talkwaqar

Hello Waqar,

Thank for letting us know. We will investigate this issue and fix it by adding an option (We cannot change the default behavior to stay backward compatible).

Could you let me know the provider you are using? (ex: SQL Server).

Best Regards,

Jonathan

JonathanMagnan avatar Dec 14 '18 12:12 JonathanMagnan

We are using SQL Server yes.

talkwaqar avatar Dec 14 '18 12:12 talkwaqar

Hello @talkwaqar ,

Just to let you know that this request will take us more time than estimated.

We successfully implemented our first solution, however, we find out that this solution had some side impact. So obviously we cannot use it.

We are currently continuing to investigate it to find a working solution.

Best Regards,

Jonathan

JonathanMagnan avatar Dec 18 '18 15:12 JonathanMagnan

@JonathanMagnan is this fixed in latest release? https://www.nuget.org/packages/Z.EntityFramework.Extensions.EFCore/2.1.45

talkwaqar avatar Jan 08 '19 12:01 talkwaqar

Hello @talkwaqar ,

We tried some solutions before the holiday break but nothing worked since our code either limit us or SQL Server syntax.

Our library is optimized for "batching" entities and currently handling this scenario with database default value require a different logic by entity since sometime we need to insert in a column and sometime not.

Currently, the only way found on our side is to create different list depending on value and recall the BulkInsert or BulkMerge. For example, a list that require to insert in the field A and a list that keep the default database value for the field A.

JonathanMagnan avatar Jan 10 '19 04:01 JonathanMagnan

Hello @talkwaqar ,

We will close this issue. As said, this options is very hard to support for "Batching" entities.

However, we will keep this request open in our internal issue tracker.

It might be perhaps easier to fix as our product evolve.

Best Regards,

Jonathan

JonathanMagnan avatar Jan 29 '19 14:01 JonathanMagnan

@JonathanMagnan is this fixed in latest release?

DeepSkyJees avatar Apr 22 '19 07:04 DeepSkyJees

Hello @NigelYu ,

No

JonathanMagnan avatar Apr 22 '19 08:04 JonathanMagnan

I'm interested in this as well. We have a lot of default values in our database design. It would be great if there was an option to override the default value when inserting.

kwasak avatar Oct 10 '19 16:10 kwasak

Hello all,

I re-opened this issue since we are currently working on a version that will allow it. I will update this issue as soon as it's ready

JonathanMagnan avatar Oct 10 '19 19:10 JonathanMagnan

Sounds great, that’s good to hear!

kwasak avatar Oct 11 '19 12:10 kwasak

I've been going crazy for a month to understand the reason for the problem, and now I find that the bulk insert ignores the value to insert because a default value is defined.

I hope a fix release will come soon

p.s. ...I am new licensed customer

fcleto avatar Dec 11 '19 14:12 fcleto

Hello all,

I re-opened this issue since we are currently working on a version that will allow it. I will update this issue as soon as it's ready

Any ETA on this?

patcor avatar Jan 15 '20 10:01 patcor

Hello all,

At this moment, the BulkInsert alone doesn't support it yet.

However, the BulkInsert + IncludeGraph = true should be now supported in the latest version. (A different strategy is used, that's why).

We have very high hope that all cases for the BulkInsert will be supported very soon.

If you have the chance to try it with the IncludeGraph = true, just let us know if something is not working correctly.

JonathanMagnan avatar Jan 28 '20 15:01 JonathanMagnan

Hello,

I have tried this, but got the exception:

'Oops! An error with IncludeGraph occurred, see the InnerException. If you use Proxy entities, the option UnsafeMode must be turned on (options.UnsafeMode = true). Contact our support team for more information: [email protected]'

That's because I set a custom connectionstring when creating a new Entities, I don't use the connectionstring in the config file. When turning UnsafeMode ON I directly get the error for 'No connection string named ....'

image

Zarkos69 avatar Jan 31 '20 16:01 Zarkos69

Hi,

I tried like the following but still the fields that has default value ignored. context.Details.BulkInsert(details.Values, opt => opt.IncludeGraph = true);

Is there any news about this issue.

skycelik avatar Dec 28 '20 09:12 skycelik

Hello @skycelik ,

Which version of EF are you using? (ex: EF6, EF Core 3.x, EF Core 5.x)

JonathanMagnan avatar Dec 28 '20 15:12 JonathanMagnan

Hello @JonathanMagnan ,

EF Core 5.x

skycelik avatar Dec 28 '20 15:12 skycelik

Hello @skycelik ,

We tried with IncludeGraph = true and everything seems to works fine for EF Core 5.x

All SQL was generated correctly in the same way SaveChanges was saving default value.

Is it possible for you to provide a runnable project with only this issue? Perhaps we are missing something else.

You can send it in private here if needed: [email protected]

JonathanMagnan avatar Dec 29 '20 17:12 JonathanMagnan

Hello @JonathanMagnan ,

Unfortinately i can not send the project because it is a big and confidential. I have to extract related code from it and prepare a sample project to send it. But i will retest, may be i did some mistakes. If i see same result, i will prepare a sample project in my first suitable time and send it to you.

Actually i only use BulkInsert in Code first migration and seed operation. There is a json file and it includes 80000 records for initial data for test environment. The data includes three boolean fields. Actually i wasn't aware the issue and i tought everything is ok. But last week i realized all the three fields in database only contains default values. So i tried to find the missing part to fix this issue. I tried with IncludeGraph = true but the result was not change. For quick fix i commented the HasDefaultValue parts for related entity in the DbContext and it worked.

As i said before. i will retest again to be sure. After testing done, i will write here the result.

skycelik avatar Dec 30 '20 05:12 skycelik

Hello @JonathanMagnan ,

I did retest and got the same result. So i tried to prepare a sample project. But when i preparing the project i realized that this issue is not related with you. So accept my apologies.

The issue is related with the EF Core itself. But i don't know if it is a bug or by design. If a boolean property has default value as true (HasDefaultValue(true)) and the property value is false at the insert time, the property returns to true after SaveChanges. I'm sure it is not related with Z.EntityFrameworkCore BulkInsert because i removed the library reference and deleted all the bulk insert codes. Just added 10 entity to DbSet and called SaveChanges.

skycelik avatar Dec 30 '20 14:12 skycelik

No need to apologize ;)

Try to make your property nullable such as bool?, I believe it might fix your problem.

EF Core probably considers false as no value has been set (since false is the default value), so it insert true.

However, if your property is nullable, null will be the default value. So when you will explicitly set it to false, then false will be inserted.

Best Regards,

Jon

JonathanMagnan avatar Dec 30 '20 16:12 JonathanMagnan

Actually i thought this too, but the interesting part is; when i remove the .HasDefaultValue(true) for property from the context, everything is ok and EF Core sends the property values to the Sql with either true or false values.

So, probably i will report bug to the EF Core team.

Thanks for your helps Jhon,

Best Regards.

skycelik avatar Dec 30 '20 17:12 skycelik

Issue persist Today on Bulk Merge

reginald81 avatar Feb 22 '21 19:02 reginald81

Any update on this issue (without using the IncludeGraph option) as we have just hit it with EF Core 6?.

Thanks

GimmieAUserName avatar Feb 24 '23 17:02 GimmieAUserName

Hello @GimmieAUserName ,

In most recent version, you should be able to avoid this issue by using the following options ForceValueGeneratedStrategy == ValueGeneratedStrategyType.OnAdd (We need to rename this option since it's really not obvious) or ForceValueGeneratedStrategy == ValueGeneratedStrategyType.OnAddOrUpdate (for BulkUpdate)

It will force our library to take the value from your entity instead of using the database default value.

Best Regards,

Jon

JonathanMagnan avatar Feb 27 '23 14:02 JonathanMagnan

Hello @GimmieAUserName ,

In most recent version, you should be able to avoid this issue by using the following options ForceValueGeneratedStrategy == ValueGeneratedStrategyType.OnAdd (We need to rename this option since it's really not obvious) or ForceValueGeneratedStrategy == ValueGeneratedStrategyType.OnAddOrUpdate (for BulkUpdate)

It will force our library to take the value from your entity instead of using the database default value.

Best Regards,

Jon

Will give it a try, thanks

GimmieAUserName avatar Feb 27 '23 14:02 GimmieAUserName

In most recent version, you should be able to avoid this issue by using the following options ForceValueGeneratedStrategy == ValueGeneratedStrategyType.OnAdd (We need to rename this option since it's really not obvious) or ForceValueGeneratedStrategy == ValueGeneratedStrategyType.OnAddOrUpdate (for BulkUpdate)

I had the same issue and I can confirm that setting ForceValueGeneratedStrategy solves it (currently testing with SQLite, if it matters at all). :+1:

Since I wasted quite a bit of time until I found this issue, it's maybe a good idea to add an hint in your website. In my opinion, you could also invest a bit more into writing meaningful summaries. Gets or sets the force value generated strategy (Might not work in some scenario with default value). and no summary at all on the enumeration doesn't make it very easy to discover.

BEagle1984 avatar Mar 14 '23 16:03 BEagle1984

Hello @GimmieAUserName ,

In most recent version, you should be able to avoid this issue by using the following options ForceValueGeneratedStrategy == ValueGeneratedStrategyType.OnAdd (We need to rename this option since it's really not obvious) or ForceValueGeneratedStrategy == ValueGeneratedStrategyType.OnAddOrUpdate (for BulkUpdate)

It will force our library to take the value from your entity instead of using the database default value.

Best Regards,

Jon

Where do I have to set this option? I have the same problem on net5 and it is solved by using: includeGraph = true

in the single instructions If I want to set the option: ForceValueGeneratedStrategy == ValueGeneratedStrategyType.OnAdd where do I have to set it? I am not able to see this option nor in BulkInsert neither in BulkMerge

Best Regards Vittorio

VittorioMorellini avatar Mar 29 '23 14:03 VittorioMorellini

I have used these options as explained but found out this option forces a one-way street. It is either using the value in code or using the value defined in SQL default constraint. I cannot have it both ways. I have a big table with many columns with defaults, and I only want to deal with the columns I need. I use the database-first approach and use scaffolding to generate my code. So if I use this ForceValueGeneratedStrategy option, I have to either comment out the HasDefaultValueSql in the generated DbContext or make sure I fill all columns with the proper default. Is this issue still being investigated? Do we have a better solution?

psham-arch avatar Apr 13 '24 14:04 psham-arch