linq2db / linq2db

Linq to database provider.
MIT License
2.97k stars 453 forks source link

[MERGE] Immutable data models are not supported #4237

Open dtila opened 1 year ago

dtila commented 1 year ago

Hi guys, I see some limitations in the library with mapped domains that are immutable.

I will take an example from documentation the MergeAPI:

db.Table
    .Merge()
    .Using(source)
    .OnTargetKey()
    .InsertWhenNotMatched(source => new TargetRecord()
    {
        Field1 = 10,
        Field2 = source.Field2,
        Field3 = source.Field1 + source.Field2
    })
    .Merge();

If I TargetRecord is immutable, then specifying properties does not work.

However with EF Core working with immutable objects work. An example are the new functions ExecuteUpdate from EF7 https://learn.microsoft.com/en-us/ef/core/saving/execute-insert-update-delete#executeupdate

context.Blogs
    .Where(b => b.Rating < 3)
    .ExecuteUpdate(setters => setters.SetProperty(b => b.IsVisible, false));

The API does this with 2 approaches:

What do you think? Do you see that this API would fit linq2db with another overload?

jods4 commented 1 year ago

Merge might be an exception, but most other operations have such api, for example:

db.Table
  .Set(x => x.Field1, 10)
  .Set(x => x.Field3, x => x.Field1 + x.Field2)
  .Update();
dtila commented 1 year ago

Thank you @jods4 , indeed I missed those since I have been using just the Merge statements :)

So I would be happy make a PR but I have issues with local development. After installing multiple .NET Full developer packs, I still miss it seems .NET4.5 where I can not find anywhere in the Microsoft.

Neither an article or some documentation I could find, so I don't have the solution working in VS2022.

BTW, are you aware of why an old pack is needed?

jods4 commented 1 year ago

As of today, linq2db still targets and supports .net 4.5:

<TargetFrameworks>net45;net46;net472;netstandard2.0;netstandard2.1;netcoreapp3.1;net6.0;net7.0</TargetFrameworks>

Installing targeting packs in VS should be enough. You should be able to do that from VS setup, they are listed amongst other options.

Otherwise you can change the target to net7.0 only, just don't forget to NOT push it in the PR. The project will be built and tested against net45 in CI anyway.

viceroypenguin commented 1 year ago

VS2022 no longer includes the netfx45 developer pack because it is so long out of support, and has so many security issues. You can find the net45 dp in the VS 2019 install, or in the win8 sdk install (https://www.gnostice.com/docs/docstudio_net/guide/_faq_buildinganddeployment_vs2022_and_netframework45.html)

dtila commented 1 year ago

@viceroypenguin I can confirm that this works with Vs2022. However, on my site running tests does not work anymore

I have created a draft extension: https://github.com/linq2db/linq2db/pull/4239 with modifications needed

I think however the InsertWhenNotMatched should accept a IQueryable and to use the existing Set Methods.

However if tests are not running, it puts me in a position impossible to do it ..