From 8e78e3d5a8b8f3530aa8122edf5809881fdb73cc Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Fri, 29 Apr 2022 17:40:06 +0800 Subject: [PATCH 01/10] feat(EntityFramework): Support EntityFrameWork --- Masa.Contrib.sln | 132 +++++++++++++++-- .../Masa.Contrib.Data.Contracts.EF/README.md | 3 - .../README.zh-CN.md | 3 - .../_Imports.cs | 0 .../Masa.Contrib.Data.Contracts.csproj | 17 +++ .../Masa.Contrib.Data.Contracts/_Imports.cs | 6 + .../Internal/Parser.cs | 26 ++++ ...rib.Data.EntityFrameworkCore.Cosmos.csproj | 17 +++ .../MasaDbContextOptionsBuilderExtensions.cs | 50 +++++++ .../README.md | 34 +++++ .../README.zh-CN.md | 34 +++++ .../_Imports.cs | 4 + ...b.Data.EntityFrameworkCore.InMemory.csproj | 18 +++ .../MasaDbContextOptionsBuilderExtensions.cs | 24 ++++ .../README.md | 33 +++++ .../README.zh-CN.md | 33 +++++ .../_Imports.cs | 7 + ...trib.Data.EntityFrameworkCore.MySql.csproj | 18 +++ .../MasaDbContextOptionsBuilderExtensions.cs | 33 +++++ .../README.md | 33 +++++ .../README.zh-CN.md | 33 +++++ .../_Imports.cs | 8 ++ ...rib.Data.EntityFrameworkCore.Oracle.csproj | 18 +++ .../MasaDbContextOptionsBuilderExtensions.cs | 33 +++++ .../README.md | 33 +++++ .../README.zh-CN.md | 33 +++++ .../_Imports.cs | 8 ++ ...ta.EntityFrameworkCore.Pomelo.MySql.csproj | 18 +++ .../MasaDbContextOptionsBuilderExtensions.cs | 36 +++++ .../README.md | 33 +++++ .../README.zh-CN.md | 33 +++++ .../_Imports.cs | 8 ++ ...Data.EntityFrameworkCore.PostgreSql.csproj | 18 +++ .../MasaDbContextOptionsBuilderExtensions.cs | 33 +++++ .../README.md | 33 +++++ .../README.zh-CN.md | 33 +++++ .../_Imports.cs | 8 ++ ....Data.EntityFrameworkCore.SqlServer.csproj | 18 +++ .../MasaDbContextOptionsBuilderExtensions.cs | 33 +++++ .../README.md | 33 +++++ .../README.zh-CN.md | 33 +++++ .../_Imports.cs | 8 ++ ...rib.Data.EntityFrameworkCore.Sqlite.csproj | 18 +++ .../MasaDbContextOptionsBuilderExtensions.cs | 33 +++++ .../README.md | 33 +++++ .../README.zh-CN.md | 33 +++++ .../_Imports.cs | 8 ++ .../DefaultConnectionStringProvider.cs | 14 ++ .../Filters/ISaveChangesFilter.cs | 6 + .../Filters/SoftDeleteSaveChangesFilter.cs | 65 +++++++++ .../IModelCreatingProvider.cs | 10 ++ .../Internal/Const.cs | 9 ++ ...a.Contrib.Data.EntityFrameworkCore.csproj} | 16 ++- ...Masa.Utils.Data.EntityFrameworkCore.csproj | 15 ++ .../MasaDbConnectionOptions.cs | 6 + .../MasaDbContext.cs | 133 ++++++++++++++++++ .../MasaDbContextOptions.cs | 21 +++ .../MasaDbContextOptionsBuilder.cs | 23 +++ .../MasaDbContextOptionsBuilder`.cs | 9 ++ .../MasaDbContextOptions`.cs | 81 +++++++++++ .../README.md | 47 +++++++ .../README.zh-CN.md | 47 +++++++ .../ServiceCollectionExtensions.cs | 94 +++++++++++++ .../_Imports.cs | 13 ++ 64 files changed, 1781 insertions(+), 22 deletions(-) delete mode 100644 src/Data/Masa.Contrib.Data.Contracts.EF/README.md delete mode 100644 src/Data/Masa.Contrib.Data.Contracts.EF/README.zh-CN.md delete mode 100644 src/Data/Masa.Contrib.Data.Contracts.EF/_Imports.cs create mode 100644 src/Data/Masa.Contrib.Data.Contracts/Masa.Contrib.Data.Contracts.csproj create mode 100644 src/Data/Masa.Contrib.Data.Contracts/_Imports.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/Internal/Parser.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/Masa.Contrib.Data.EntityFrameworkCore.Cosmos.csproj create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/MasaDbContextOptionsBuilderExtensions.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.zh-CN.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/_Imports.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/Masa.Contrib.Data.EntityFrameworkCore.InMemory.csproj create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/MasaDbContextOptionsBuilderExtensions.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.zh-CN.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/_Imports.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/Masa.Contrib.Data.EntityFrameworkCore.MySql.csproj create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/MasaDbContextOptionsBuilderExtensions.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.zh-CN.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/_Imports.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/Masa.Contrib.Data.EntityFrameworkCore.Oracle.csproj create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/MasaDbContextOptionsBuilderExtensions.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.zh-CN.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/_Imports.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql.csproj create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/MasaDbContextOptionsBuilderExtensions.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.zh-CN.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/_Imports.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql.csproj create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/MasaDbContextOptionsBuilderExtensions.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.zh-CN.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/_Imports.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/Masa.Contrib.Data.EntityFrameworkCore.SqlServer.csproj create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/MasaDbContextOptionsBuilderExtensions.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.zh-CN.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/_Imports.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/Masa.Contrib.Data.EntityFrameworkCore.Sqlite.csproj create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/MasaDbContextOptionsBuilderExtensions.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.zh-CN.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/_Imports.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/DefaultConnectionStringProvider.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/ISaveChangesFilter.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/SoftDeleteSaveChangesFilter.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/IModelCreatingProvider.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/Internal/Const.cs rename src/Data/{Masa.Contrib.Data.Contracts.EF/Masa.Contrib.Data.Contracts.EF.csproj => Masa.Contrib.Data.EntityFrameworkCore/Masa.Contrib.Data.EntityFrameworkCore.csproj} (50%) create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Utils.Data.EntityFrameworkCore.csproj create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbConnectionOptions.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContext.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder`.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions`.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.zh-CN.md create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/ServiceCollectionExtensions.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/_Imports.cs diff --git a/Masa.Contrib.sln b/Masa.Contrib.sln index 8c8c7781c..0e9c65675 100644 --- a/Masa.Contrib.sln +++ b/Masa.Contrib.sln @@ -68,8 +68,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Ddd.Domain", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Ddd.Domain.Repository.EF", "src\Ddd\Masa.Contrib.Ddd.Domain.Repository.EF\Masa.Contrib.Ddd.Domain.Repository.EF.csproj", "{D375233D-8AAC-4234-BC0D-3D103C600C19}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Data.Contracts.EF", "src\Data\Masa.Contrib.Data.Contracts.EF\Masa.Contrib.Data.Contracts.EF.csproj", "{33F3BA7C-5BCB-4FB5-8E7E-2F7E29D92012}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Ddd.Domain.Tests", "test\Masa.Contrib.Ddd.Domain.Tests\Masa.Contrib.Ddd.Domain.Tests.csproj", "{EAC0AA32-AE9B-4908-AF05-927B70A2B8A1}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.Ddd.Domain.Repository.EF.Tests", "test\Masa.Contrib.Ddd.Domain.Repository.EF.Tests\Masa.Contrib.Ddd.Domain.Repository.EF.Tests.csproj", "{E893C913-98A0-4BB3-A32B-3871BE3C5C53}" @@ -172,6 +170,28 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Storage", "Storage", "{1653 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Configuration.AutoMap.NoArgumentConstructor.Tests", "test\Masa.Contrib.Configuration.AutoMap.NoArgumentConstructor.Tests\Masa.Contrib.Configuration.AutoMap.NoArgumentConstructor.Tests.csproj", "{B8358ED1-C95A-4EC0-9756-FB32C931F204}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.Contracts", "src\Data\Masa.Contrib.Data.Contracts\Masa.Contrib.Data.Contracts.csproj", "{79D639DC-DDE4-45B1-884D-60B6908F528E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Data", "src\BuildingBlocks\MASA.BuildingBlocks\src\Data\Masa.BuildingBlocks.Data\Masa.BuildingBlocks.Data.csproj", "{C3451307-3743-4911-A401-7F28889703D3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFrameworkCore", "src\Data\Masa.Contrib.Data.EntityFrameworkCore\Masa.Contrib.Data.EntityFrameworkCore.csproj", "{87DD354D-4D48-4918-ACDE-A7FF62FA0DD8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFrameworkCore.Cosmos", "src\Data\Masa.Contrib.Data.EntityFrameworkCore.Cosmos\Masa.Contrib.Data.EntityFrameworkCore.Cosmos.csproj", "{3236F880-3DC0-450F-A14D-8C87525845DD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFrameworkCore.InMemory", "src\Data\Masa.Contrib.Data.EntityFrameworkCore.InMemory\Masa.Contrib.Data.EntityFrameworkCore.InMemory.csproj", "{7E3FAE39-9CD1-46FA-A389-660008035DFB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFrameworkCore.MySql", "src\Data\Masa.Contrib.Data.EntityFrameworkCore.MySql\Masa.Contrib.Data.EntityFrameworkCore.MySql.csproj", "{3F19EBF9-A52E-4D64-8884-ECB16BE6A12A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFrameworkCore.Oracle", "src\Data\Masa.Contrib.Data.EntityFrameworkCore.Oracle\Masa.Contrib.Data.EntityFrameworkCore.Oracle.csproj", "{A42CCFB3-1C30-4A58-AB28-E28736BF5378}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql", "src\Data\Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql\Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql.csproj", "{32E7A2E4-EE91-4CEA-9EBD-9EFE1C03CF48}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFrameworkCore.PostgreSql", "src\Data\Masa.Contrib.Data.EntityFrameworkCore.PostgreSql\Masa.Contrib.Data.EntityFrameworkCore.PostgreSql.csproj", "{A50DC3FB-FD2A-4EF8-8333-4782DFFF0BF1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFrameworkCore.Sqlite", "src\Data\Masa.Contrib.Data.EntityFrameworkCore.Sqlite\Masa.Contrib.Data.EntityFrameworkCore.Sqlite.csproj", "{C8CE5B92-96A6-4FA1-9EEB-43A524DC54AA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFrameworkCore.SqlServer", "src\Data\Masa.Contrib.Data.EntityFrameworkCore.SqlServer\Masa.Contrib.Data.EntityFrameworkCore.SqlServer.csproj", "{E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -300,14 +320,6 @@ Global {D375233D-8AAC-4234-BC0D-3D103C600C19}.Release|Any CPU.Build.0 = Release|Any CPU {D375233D-8AAC-4234-BC0D-3D103C600C19}.Release|x64.ActiveCfg = Release|Any CPU {D375233D-8AAC-4234-BC0D-3D103C600C19}.Release|x64.Build.0 = Release|Any CPU - {33F3BA7C-5BCB-4FB5-8E7E-2F7E29D92012}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {33F3BA7C-5BCB-4FB5-8E7E-2F7E29D92012}.Debug|Any CPU.Build.0 = Debug|Any CPU - {33F3BA7C-5BCB-4FB5-8E7E-2F7E29D92012}.Debug|x64.ActiveCfg = Debug|Any CPU - {33F3BA7C-5BCB-4FB5-8E7E-2F7E29D92012}.Debug|x64.Build.0 = Debug|Any CPU - {33F3BA7C-5BCB-4FB5-8E7E-2F7E29D92012}.Release|Any CPU.ActiveCfg = Release|Any CPU - {33F3BA7C-5BCB-4FB5-8E7E-2F7E29D92012}.Release|Any CPU.Build.0 = Release|Any CPU - {33F3BA7C-5BCB-4FB5-8E7E-2F7E29D92012}.Release|x64.ActiveCfg = Release|Any CPU - {33F3BA7C-5BCB-4FB5-8E7E-2F7E29D92012}.Release|x64.Build.0 = Release|Any CPU {EAC0AA32-AE9B-4908-AF05-927B70A2B8A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EAC0AA32-AE9B-4908-AF05-927B70A2B8A1}.Debug|Any CPU.Build.0 = Debug|Any CPU {EAC0AA32-AE9B-4908-AF05-927B70A2B8A1}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -676,6 +688,94 @@ Global {B8358ED1-C95A-4EC0-9756-FB32C931F204}.Release|Any CPU.Build.0 = Release|Any CPU {B8358ED1-C95A-4EC0-9756-FB32C931F204}.Release|x64.ActiveCfg = Release|Any CPU {B8358ED1-C95A-4EC0-9756-FB32C931F204}.Release|x64.Build.0 = Release|Any CPU + {79D639DC-DDE4-45B1-884D-60B6908F528E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {79D639DC-DDE4-45B1-884D-60B6908F528E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {79D639DC-DDE4-45B1-884D-60B6908F528E}.Debug|x64.ActiveCfg = Debug|Any CPU + {79D639DC-DDE4-45B1-884D-60B6908F528E}.Debug|x64.Build.0 = Debug|Any CPU + {79D639DC-DDE4-45B1-884D-60B6908F528E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {79D639DC-DDE4-45B1-884D-60B6908F528E}.Release|Any CPU.Build.0 = Release|Any CPU + {79D639DC-DDE4-45B1-884D-60B6908F528E}.Release|x64.ActiveCfg = Release|Any CPU + {79D639DC-DDE4-45B1-884D-60B6908F528E}.Release|x64.Build.0 = Release|Any CPU + {C3451307-3743-4911-A401-7F28889703D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3451307-3743-4911-A401-7F28889703D3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3451307-3743-4911-A401-7F28889703D3}.Debug|x64.ActiveCfg = Debug|Any CPU + {C3451307-3743-4911-A401-7F28889703D3}.Debug|x64.Build.0 = Debug|Any CPU + {C3451307-3743-4911-A401-7F28889703D3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3451307-3743-4911-A401-7F28889703D3}.Release|Any CPU.Build.0 = Release|Any CPU + {C3451307-3743-4911-A401-7F28889703D3}.Release|x64.ActiveCfg = Release|Any CPU + {C3451307-3743-4911-A401-7F28889703D3}.Release|x64.Build.0 = Release|Any CPU + {87DD354D-4D48-4918-ACDE-A7FF62FA0DD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87DD354D-4D48-4918-ACDE-A7FF62FA0DD8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87DD354D-4D48-4918-ACDE-A7FF62FA0DD8}.Debug|x64.ActiveCfg = Debug|Any CPU + {87DD354D-4D48-4918-ACDE-A7FF62FA0DD8}.Debug|x64.Build.0 = Debug|Any CPU + {87DD354D-4D48-4918-ACDE-A7FF62FA0DD8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87DD354D-4D48-4918-ACDE-A7FF62FA0DD8}.Release|Any CPU.Build.0 = Release|Any CPU + {87DD354D-4D48-4918-ACDE-A7FF62FA0DD8}.Release|x64.ActiveCfg = Release|Any CPU + {87DD354D-4D48-4918-ACDE-A7FF62FA0DD8}.Release|x64.Build.0 = Release|Any CPU + {3236F880-3DC0-450F-A14D-8C87525845DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3236F880-3DC0-450F-A14D-8C87525845DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3236F880-3DC0-450F-A14D-8C87525845DD}.Debug|x64.ActiveCfg = Debug|Any CPU + {3236F880-3DC0-450F-A14D-8C87525845DD}.Debug|x64.Build.0 = Debug|Any CPU + {3236F880-3DC0-450F-A14D-8C87525845DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3236F880-3DC0-450F-A14D-8C87525845DD}.Release|Any CPU.Build.0 = Release|Any CPU + {3236F880-3DC0-450F-A14D-8C87525845DD}.Release|x64.ActiveCfg = Release|Any CPU + {3236F880-3DC0-450F-A14D-8C87525845DD}.Release|x64.Build.0 = Release|Any CPU + {7E3FAE39-9CD1-46FA-A389-660008035DFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7E3FAE39-9CD1-46FA-A389-660008035DFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7E3FAE39-9CD1-46FA-A389-660008035DFB}.Debug|x64.ActiveCfg = Debug|Any CPU + {7E3FAE39-9CD1-46FA-A389-660008035DFB}.Debug|x64.Build.0 = Debug|Any CPU + {7E3FAE39-9CD1-46FA-A389-660008035DFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7E3FAE39-9CD1-46FA-A389-660008035DFB}.Release|Any CPU.Build.0 = Release|Any CPU + {7E3FAE39-9CD1-46FA-A389-660008035DFB}.Release|x64.ActiveCfg = Release|Any CPU + {7E3FAE39-9CD1-46FA-A389-660008035DFB}.Release|x64.Build.0 = Release|Any CPU + {3F19EBF9-A52E-4D64-8884-ECB16BE6A12A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3F19EBF9-A52E-4D64-8884-ECB16BE6A12A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3F19EBF9-A52E-4D64-8884-ECB16BE6A12A}.Debug|x64.ActiveCfg = Debug|Any CPU + {3F19EBF9-A52E-4D64-8884-ECB16BE6A12A}.Debug|x64.Build.0 = Debug|Any CPU + {3F19EBF9-A52E-4D64-8884-ECB16BE6A12A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3F19EBF9-A52E-4D64-8884-ECB16BE6A12A}.Release|Any CPU.Build.0 = Release|Any CPU + {3F19EBF9-A52E-4D64-8884-ECB16BE6A12A}.Release|x64.ActiveCfg = Release|Any CPU + {3F19EBF9-A52E-4D64-8884-ECB16BE6A12A}.Release|x64.Build.0 = Release|Any CPU + {A42CCFB3-1C30-4A58-AB28-E28736BF5378}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A42CCFB3-1C30-4A58-AB28-E28736BF5378}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A42CCFB3-1C30-4A58-AB28-E28736BF5378}.Debug|x64.ActiveCfg = Debug|Any CPU + {A42CCFB3-1C30-4A58-AB28-E28736BF5378}.Debug|x64.Build.0 = Debug|Any CPU + {A42CCFB3-1C30-4A58-AB28-E28736BF5378}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A42CCFB3-1C30-4A58-AB28-E28736BF5378}.Release|Any CPU.Build.0 = Release|Any CPU + {A42CCFB3-1C30-4A58-AB28-E28736BF5378}.Release|x64.ActiveCfg = Release|Any CPU + {A42CCFB3-1C30-4A58-AB28-E28736BF5378}.Release|x64.Build.0 = Release|Any CPU + {32E7A2E4-EE91-4CEA-9EBD-9EFE1C03CF48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {32E7A2E4-EE91-4CEA-9EBD-9EFE1C03CF48}.Debug|Any CPU.Build.0 = Debug|Any CPU + {32E7A2E4-EE91-4CEA-9EBD-9EFE1C03CF48}.Debug|x64.ActiveCfg = Debug|Any CPU + {32E7A2E4-EE91-4CEA-9EBD-9EFE1C03CF48}.Debug|x64.Build.0 = Debug|Any CPU + {32E7A2E4-EE91-4CEA-9EBD-9EFE1C03CF48}.Release|Any CPU.ActiveCfg = Release|Any CPU + {32E7A2E4-EE91-4CEA-9EBD-9EFE1C03CF48}.Release|Any CPU.Build.0 = Release|Any CPU + {32E7A2E4-EE91-4CEA-9EBD-9EFE1C03CF48}.Release|x64.ActiveCfg = Release|Any CPU + {32E7A2E4-EE91-4CEA-9EBD-9EFE1C03CF48}.Release|x64.Build.0 = Release|Any CPU + {A50DC3FB-FD2A-4EF8-8333-4782DFFF0BF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A50DC3FB-FD2A-4EF8-8333-4782DFFF0BF1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A50DC3FB-FD2A-4EF8-8333-4782DFFF0BF1}.Debug|x64.ActiveCfg = Debug|Any CPU + {A50DC3FB-FD2A-4EF8-8333-4782DFFF0BF1}.Debug|x64.Build.0 = Debug|Any CPU + {A50DC3FB-FD2A-4EF8-8333-4782DFFF0BF1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A50DC3FB-FD2A-4EF8-8333-4782DFFF0BF1}.Release|Any CPU.Build.0 = Release|Any CPU + {A50DC3FB-FD2A-4EF8-8333-4782DFFF0BF1}.Release|x64.ActiveCfg = Release|Any CPU + {A50DC3FB-FD2A-4EF8-8333-4782DFFF0BF1}.Release|x64.Build.0 = Release|Any CPU + {C8CE5B92-96A6-4FA1-9EEB-43A524DC54AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C8CE5B92-96A6-4FA1-9EEB-43A524DC54AA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C8CE5B92-96A6-4FA1-9EEB-43A524DC54AA}.Debug|x64.ActiveCfg = Debug|Any CPU + {C8CE5B92-96A6-4FA1-9EEB-43A524DC54AA}.Debug|x64.Build.0 = Debug|Any CPU + {C8CE5B92-96A6-4FA1-9EEB-43A524DC54AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C8CE5B92-96A6-4FA1-9EEB-43A524DC54AA}.Release|Any CPU.Build.0 = Release|Any CPU + {C8CE5B92-96A6-4FA1-9EEB-43A524DC54AA}.Release|x64.ActiveCfg = Release|Any CPU + {C8CE5B92-96A6-4FA1-9EEB-43A524DC54AA}.Release|x64.Build.0 = Release|Any CPU + {E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE}.Debug|x64.ActiveCfg = Debug|Any CPU + {E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE}.Debug|x64.Build.0 = Debug|Any CPU + {E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE}.Release|Any CPU.Build.0 = Release|Any CPU + {E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE}.Release|x64.ActiveCfg = Release|Any CPU + {E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -709,7 +809,6 @@ Global {EA23C277-97E4-4FBC-A53B-37048813E14F} = {DA885E64-C5E2-4C22-8C2A-26E68A593F29} {0FF64D9E-98D7-46B1-90FB-C0364C76D65A} = {21180442-A6A5-4239-A2AD-33FF5BB80E72} {D375233D-8AAC-4234-BC0D-3D103C600C19} = {21180442-A6A5-4239-A2AD-33FF5BB80E72} - {33F3BA7C-5BCB-4FB5-8E7E-2F7E29D92012} = {E33ADF54-4D35-49B7-BDA6-412587CA39FF} {EAC0AA32-AE9B-4908-AF05-927B70A2B8A1} = {13EDB361-AF88-4F89-B4AB-46622BCCBC37} {E893C913-98A0-4BB3-A32B-3871BE3C5C53} = {880E8263-AECC-4793-BD28-7CD03650D124} {761C3313-A669-465F-A384-9E118FCE4F89} = {38E6C400-90C0-493E-9266-C1602E229F1B} @@ -761,6 +860,17 @@ Global {97532A33-A591-4DF5-A2C0-72527B78ED82} = {38E6C400-90C0-493E-9266-C1602E229F1B} {165391A5-034E-4894-8084-8DF7D4AA7518} = {42DF7AAC-362C-48F4-B76A-BDEEEFF17CC9} {B8358ED1-C95A-4EC0-9756-FB32C931F204} = {9EEE31DA-3165-4CB3-AAE9-27CC3A4DE669} + {79D639DC-DDE4-45B1-884D-60B6908F528E} = {E33ADF54-4D35-49B7-BDA6-412587CA39FF} + {C3451307-3743-4911-A401-7F28889703D3} = {DC578D74-98F0-4F19-A230-CFA8DAEE0AF1} + {87DD354D-4D48-4918-ACDE-A7FF62FA0DD8} = {E33ADF54-4D35-49B7-BDA6-412587CA39FF} + {3236F880-3DC0-450F-A14D-8C87525845DD} = {E33ADF54-4D35-49B7-BDA6-412587CA39FF} + {7E3FAE39-9CD1-46FA-A389-660008035DFB} = {E33ADF54-4D35-49B7-BDA6-412587CA39FF} + {3F19EBF9-A52E-4D64-8884-ECB16BE6A12A} = {E33ADF54-4D35-49B7-BDA6-412587CA39FF} + {A42CCFB3-1C30-4A58-AB28-E28736BF5378} = {E33ADF54-4D35-49B7-BDA6-412587CA39FF} + {32E7A2E4-EE91-4CEA-9EBD-9EFE1C03CF48} = {E33ADF54-4D35-49B7-BDA6-412587CA39FF} + {A50DC3FB-FD2A-4EF8-8333-4782DFFF0BF1} = {E33ADF54-4D35-49B7-BDA6-412587CA39FF} + {C8CE5B92-96A6-4FA1-9EEB-43A524DC54AA} = {E33ADF54-4D35-49B7-BDA6-412587CA39FF} + {E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE} = {E33ADF54-4D35-49B7-BDA6-412587CA39FF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03} diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/README.md b/src/Data/Masa.Contrib.Data.Contracts.EF/README.md deleted file mode 100644 index 053f9760a..000000000 --- a/src/Data/Masa.Contrib.Data.Contracts.EF/README.md +++ /dev/null @@ -1,3 +0,0 @@ -[中](README.zh-CN.md) | EN - -## Contracts.EF \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/README.zh-CN.md b/src/Data/Masa.Contrib.Data.Contracts.EF/README.zh-CN.md deleted file mode 100644 index 2d2ba01b0..000000000 --- a/src/Data/Masa.Contrib.Data.Contracts.EF/README.zh-CN.md +++ /dev/null @@ -1,3 +0,0 @@ -中 | [EN](README.md) - -## Contracts.EF \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/_Imports.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/_Imports.cs deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/Data/Masa.Contrib.Data.Contracts/Masa.Contrib.Data.Contracts.csproj b/src/Data/Masa.Contrib.Data.Contracts/Masa.Contrib.Data.Contracts.csproj new file mode 100644 index 000000000..8bcb428a5 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.Contracts/Masa.Contrib.Data.Contracts.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + diff --git a/src/Data/Masa.Contrib.Data.Contracts/_Imports.cs b/src/Data/Masa.Contrib.Data.Contracts/_Imports.cs new file mode 100644 index 000000000..ec8f2bb57 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.Contracts/_Imports.cs @@ -0,0 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using System.Collections.Concurrent; +global using Masa.BuildingBlocks.Data.Contracts.DataFiltering; +global using Microsoft.Extensions.DependencyInjection; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/Internal/Parser.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/Internal/Parser.cs new file mode 100644 index 000000000..f734442a5 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/Internal/Parser.cs @@ -0,0 +1,26 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Cosmos.Internal; + +internal static class Parser +{ + public static Dictionary ToDictionary(this string connectionString) + { + if (string.IsNullOrEmpty(connectionString)) + throw new ArgumentException("Cosmos: empty database connection string", nameof(connectionString)); + + Dictionary dictionary = new(); + foreach (var item in connectionString.Split(';')) + { + if (string.IsNullOrEmpty(item)) + continue; + + if (item.Split('=').Length != 2) + throw new ArgumentException("Cosmos: Bad database connection string"); + + dictionary.Add(item.Split('=')[0], item.Split('=')[1]); + } + return dictionary; + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/Masa.Contrib.Data.EntityFrameworkCore.Cosmos.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/Masa.Contrib.Data.EntityFrameworkCore.Cosmos.csproj new file mode 100644 index 000000000..16a6815c5 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/Masa.Contrib.Data.EntityFrameworkCore.Cosmos.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/MasaDbContextOptionsBuilderExtensions.cs new file mode 100644 index 000000000..c2e4f4835 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/MasaDbContextOptionsBuilderExtensions.cs @@ -0,0 +1,50 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +using Masa.BuildingBlocks.Data; + +namespace Masa.Contrib.Data.EntityFrameworkCore.Cosmos; + +public static class MasaDbContextOptionsBuilderExtensions +{ + public static MasaDbContextOptionsBuilder UseCosmos( + this MasaDbContextOptionsBuilder builder, + Action? cosmosOptionsAction = null) + { + var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); + var configurationDic = connectionStringProvider.GetConnectionString().ToDictionary(); + + if (!configurationDic.TryGetValue("Database", out string? databaseName)) + throw new ArgumentException("Cosmos: Bad database connection string, Failed to get [Database] name"); + + if (configurationDic.TryGetValue("ConnectionString", out string? connectionString)) + return builder.UseCosmos(connectionString, databaseName, cosmosOptionsAction); + + if (!configurationDic.TryGetValue("AccountKey", out string? accountKey) || + !configurationDic.TryGetValue("AccountEndpoint", out string? accountEndpoint)) + throw new ArgumentException("Cosmos: Bad database connection string, Failed to get [AccountKey] name or [AccountEndpoint] name"); + + return builder.UseCosmos(accountEndpoint, accountKey, databaseName, cosmosOptionsAction); + } + + public static MasaDbContextOptionsBuilder UseCosmos( + this MasaDbContextOptionsBuilder builder, + string accountEndpoint, + string accountKey, + string databaseName, + Action? cosmosOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseCosmos(accountEndpoint, accountKey, databaseName, cosmosOptionsAction); + return builder; + } + + public static MasaDbContextOptionsBuilder UseCosmos( + this MasaDbContextOptionsBuilder builder, + string connectionString, + string databaseName, + Action? cosmosOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseCosmos(connectionString, databaseName, cosmosOptionsAction); + return builder; + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.md new file mode 100644 index 000000000..8c9c1eaab --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.md @@ -0,0 +1,34 @@ +[中](README.zh-CN.md) | EN + +## Masa.Contrib.Data.EntityFrameworkCore.Cosmos + +## Example: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.Cosmos +``` + +##### Usage 1: + +1. Configure appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "AccountKey=AccountKey;AccountEndpoint=AccountEndpoint;Database=Database"// or "ConnectionString=ConnectionString;Database=Database" + } +} +``` + +2. Using MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseCosmos()); +``` + +##### Usage 2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseCosmos($"{accountEndpoint}",$"{accountKey}",$"{databaseName}")); +//builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseCosmos($"{connectionString}",$"{databaseName}")); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.zh-CN.md new file mode 100644 index 000000000..b1b62c4f6 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.zh-CN.md @@ -0,0 +1,34 @@ +中 | [EN](README.md) + +## Masa.Contrib.Data.EntityFrameworkCore.Cosmos + +## 用例: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.Cosmos +``` + +#### 用法1: + +1. 配置appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "AccountKey=AccountKey;AccountEndpoint=AccountEndpoint;Database=Database"//或"ConnectionString=ConnectionString;Database=Database" + } +} +``` + +2. 使用MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseCosmos()); +``` + +#### 用法2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseCosmos($"{accountEndpoint}",$"{accountKey}",$"{databaseName}")); +//builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseCosmos($"{connectionString}",$"{databaseName}")); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/_Imports.cs new file mode 100644 index 000000000..65640bc1f --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/_Imports.cs @@ -0,0 +1,4 @@ +global using Masa.Contrib.Data.EntityFrameworkCore.Cosmos.Internal; +global using Microsoft.EntityFrameworkCore; +global using Microsoft.EntityFrameworkCore.Infrastructure; +global using Microsoft.Extensions.DependencyInjection; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/Masa.Contrib.Data.EntityFrameworkCore.InMemory.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/Masa.Contrib.Data.EntityFrameworkCore.InMemory.csproj new file mode 100644 index 000000000..693d26f36 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/Masa.Contrib.Data.EntityFrameworkCore.InMemory.csproj @@ -0,0 +1,18 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/MasaDbContextOptionsBuilderExtensions.cs new file mode 100644 index 000000000..2768c8bb3 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/MasaDbContextOptionsBuilderExtensions.cs @@ -0,0 +1,24 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.InMemory; + +public static class MasaDbContextOptionsBuilderExtensions +{ + public static MasaDbContextOptionsBuilder UseInMemoryDatabase( + this MasaDbContextOptionsBuilder builder, + Action? inMemoryOptionsAction = null) + { + var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); + return builder.UseInMemoryDatabase(connectionStringProvider.GetConnectionString(), inMemoryOptionsAction); + } + + public static MasaDbContextOptionsBuilder UseInMemoryDatabase( + this MasaDbContextOptionsBuilder builder, + string databaseName, + Action? inMemoryOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseInMemoryDatabase(databaseName, inMemoryOptionsAction); + return builder; + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.md new file mode 100644 index 000000000..f9c193b86 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.md @@ -0,0 +1,33 @@ +[中](README.zh-CN.md) | EN + +## Masa.Contrib.Data.EntityFrameworkCore.InMemory + +## Example: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.InMemory +``` + +##### Usage 1: + +1. Configure appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "identity" + } +} +``` + +2. Using MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseInMemoryDatabase()); +``` + +##### Usage 2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseInMemoryDatabase("identity")); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.zh-CN.md new file mode 100644 index 000000000..449197f2c --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.zh-CN.md @@ -0,0 +1,33 @@ +中 | [EN](README.md) + +## Masa.Contrib.Data.EntityFrameworkCore.InMemory + +## 用例: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.InMemory +``` + +#### 用法1: + +1. 配置appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "identity" + } +} +``` + +2. 使用MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseInMemoryDatabase()); +``` + +#### 用法2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseInMemoryDatabase("identity")); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/_Imports.cs new file mode 100644 index 000000000..0c0403d0b --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/_Imports.cs @@ -0,0 +1,7 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Data; +global using Microsoft.EntityFrameworkCore; +global using Microsoft.EntityFrameworkCore.Infrastructure; +global using Microsoft.Extensions.DependencyInjection; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/Masa.Contrib.Data.EntityFrameworkCore.MySql.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/Masa.Contrib.Data.EntityFrameworkCore.MySql.csproj new file mode 100644 index 000000000..96a55bb18 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/Masa.Contrib.Data.EntityFrameworkCore.MySql.csproj @@ -0,0 +1,18 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/MasaDbContextOptionsBuilderExtensions.cs new file mode 100644 index 000000000..f32e9e66a --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/MasaDbContextOptionsBuilderExtensions.cs @@ -0,0 +1,33 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.MySql; + +public static class MasaDbContextOptionsBuilderExtensions +{ + public static MasaDbContextOptionsBuilder UseMySQL( + this MasaDbContextOptionsBuilder builder, + Action? mySqlOptionsAction = null) + { + var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); + return builder.UseMySQL(connectionStringProvider.GetConnectionString(), mySqlOptionsAction); + } + + public static MasaDbContextOptionsBuilder UseMySQL( + this MasaDbContextOptionsBuilder builder, + string connectionString, + Action? mySqlOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseMySQL(connectionString, mySqlOptionsAction); + return builder; + } + + public static MasaDbContextOptionsBuilder UseMySQL( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + Action? mySqlOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseMySQL(connection, mySqlOptionsAction); + return builder; + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.md new file mode 100644 index 000000000..3a24ada64 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.md @@ -0,0 +1,33 @@ +[中](README.zh-CN.md) | EN + +## Masa.Contrib.Data.EntityFrameworkCore.MySql + +## Example: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.MySql +``` + +##### Usage 1: + +1. Configure appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;" + } +} +``` + +2. Using MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySQL()); +``` + +##### Usage 2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySQL("Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;")); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.zh-CN.md new file mode 100644 index 000000000..6e4b4a057 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.zh-CN.md @@ -0,0 +1,33 @@ +中 | [EN](README.md) + +## Masa.Contrib.Data.EntityFrameworkCore.MySql + +## 用例: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.MySql +``` + +#### 用法1: + +1. 配置appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;" + } +} +``` + +2. 使用MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySQL()); +``` + +#### 用法2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySQL("Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;")); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/_Imports.cs new file mode 100644 index 000000000..8d90ceb61 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/_Imports.cs @@ -0,0 +1,8 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Data; +global using Microsoft.EntityFrameworkCore; +global using Microsoft.Extensions.DependencyInjection; +global using MySql.EntityFrameworkCore.Infrastructure; +global using System.Data.Common; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/Masa.Contrib.Data.EntityFrameworkCore.Oracle.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/Masa.Contrib.Data.EntityFrameworkCore.Oracle.csproj new file mode 100644 index 000000000..38d86a4c7 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/Masa.Contrib.Data.EntityFrameworkCore.Oracle.csproj @@ -0,0 +1,18 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/MasaDbContextOptionsBuilderExtensions.cs new file mode 100644 index 000000000..65c3560d8 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/MasaDbContextOptionsBuilderExtensions.cs @@ -0,0 +1,33 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Oracle; + +public static class MasaDbContextOptionsBuilderExtensions +{ + public static MasaDbContextOptionsBuilder UseOracle( + this MasaDbContextOptionsBuilder builder, + Action? oracleOptionsAction = null) + { + var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); + return builder.UseOracle(connectionStringProvider.GetConnectionString(), oracleOptionsAction); + } + + public static MasaDbContextOptionsBuilder UseOracle( + this MasaDbContextOptionsBuilder builder, + string connectionString, + Action? oracleOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseOracle(connectionString, oracleOptionsAction); + return builder; + } + + public static MasaDbContextOptionsBuilder UseOracle( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + Action? oracleOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseOracle(connection, oracleOptionsAction); + return builder; + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.md new file mode 100644 index 000000000..8967cc155 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.md @@ -0,0 +1,33 @@ +[中](README.zh-CN.md) | EN + +## Masa.Contrib.Data.EntityFrameworkCore.Oracle + +## Example: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.Oracle +``` + +##### Usage 1: + +1. Configure appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "Data Source=MyOracleDB;Integrated Security=yes;" + } +} +``` + +2. Using MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseOracle()); +``` + +##### Usage 2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseOracle("Data Source=MyOracleDB;Integrated Security=yes;")); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.zh-CN.md new file mode 100644 index 000000000..4ebf69c70 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.zh-CN.md @@ -0,0 +1,33 @@ +中 | [EN](README.md) + +## Masa.Contrib.Data.EntityFrameworkCore.Oracle + +## 用例: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.Oracle +``` + +#### 用法1: + +1. 配置appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "Data Source=MyOracleDB;Integrated Security=yes;" + } +} +``` + +2. 使用MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseOracle()); +``` + +#### 用法2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseOracle("Data Source=MyOracleDB;Integrated Security=yes;")); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/_Imports.cs new file mode 100644 index 000000000..cd83d66a6 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/_Imports.cs @@ -0,0 +1,8 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Data; +global using Microsoft.EntityFrameworkCore; +global using Microsoft.Extensions.DependencyInjection; +global using Oracle.EntityFrameworkCore.Infrastructure; +global using System.Data.Common; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql.csproj new file mode 100644 index 000000000..595de2cda --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql.csproj @@ -0,0 +1,18 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/MasaDbContextOptionsBuilderExtensions.cs new file mode 100644 index 000000000..535816571 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/MasaDbContextOptionsBuilderExtensions.cs @@ -0,0 +1,36 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql; + +public static class MasaDbContextOptionsBuilderExtensions +{ + public static MasaDbContextOptionsBuilder UseMySql( + this MasaDbContextOptionsBuilder builder, + ServerVersion serverVersion, + Action? mySqlOptionsAction = null) + { + var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); + return builder.UseMySql(connectionStringProvider.GetConnectionString(), serverVersion, mySqlOptionsAction); + } + + public static MasaDbContextOptionsBuilder UseMySql( + this MasaDbContextOptionsBuilder builder, + string connectionString, + ServerVersion serverVersion, + Action? mySqlOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseMySql(connectionString, serverVersion, mySqlOptionsAction); + return builder; + } + + public static MasaDbContextOptionsBuilder UseMySql( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + ServerVersion serverVersion, + Action? mySqlOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseMySql(connection, serverVersion, mySqlOptionsAction); + return builder; + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.md new file mode 100644 index 000000000..09b00ab60 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.md @@ -0,0 +1,33 @@ +[中](README.zh-CN.md) | EN + +## Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql + +## Example: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql +``` + +##### Usage 1: + +1. Configure appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;" + } +} +``` + +2. Using MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySql(Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.28-mysql"))); +``` + +##### Usage 2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySql("Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;", Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.28-mysql"))); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.zh-CN.md new file mode 100644 index 000000000..0b2c8b376 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.zh-CN.md @@ -0,0 +1,33 @@ +中 | [EN](README.md) + +## Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql + +## 用例: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql +``` + +#### 用法1: + +1. 配置appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;" + } +} +``` + +2. 使用MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySql(Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.28-mysql"))); +``` + +#### 用法2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySql("Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;", Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.28-mysql"))); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/_Imports.cs new file mode 100644 index 000000000..6c838c511 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/_Imports.cs @@ -0,0 +1,8 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Data; +global using Microsoft.EntityFrameworkCore; +global using Microsoft.EntityFrameworkCore.Infrastructure; +global using Microsoft.Extensions.DependencyInjection; +global using System.Data.Common; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql.csproj new file mode 100644 index 000000000..e44d41277 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql.csproj @@ -0,0 +1,18 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/MasaDbContextOptionsBuilderExtensions.cs new file mode 100644 index 000000000..a5a2f3505 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/MasaDbContextOptionsBuilderExtensions.cs @@ -0,0 +1,33 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.PostgreSql; + +public static class MasaDbContextOptionsBuilderExtensions +{ + public static MasaDbContextOptionsBuilder UseNpgsql( + this MasaDbContextOptionsBuilder builder, + Action? npgsqlOptionsAction = null) + { + var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); + return builder.UseNpgsql(connectionStringProvider.GetConnectionString(), npgsqlOptionsAction); + } + + public static MasaDbContextOptionsBuilder UseNpgsql( + this MasaDbContextOptionsBuilder builder, + string connectionString, + Action? npgsqlOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseNpgsql(connectionString, npgsqlOptionsAction); + return builder; + } + + public static MasaDbContextOptionsBuilder UseNpgsql( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + Action? npgsqlOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseNpgsql(connection, npgsqlOptionsAction); + return builder; + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.md new file mode 100644 index 000000000..5f14aef33 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.md @@ -0,0 +1,33 @@ +[中](README.zh-CN.md) | EN + +## Masa.Contrib.Data.EntityFrameworkCore.PostgreSql + +## Example: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.PostgreSql +``` + +##### Usage 1: + +1. Configure appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "Host=myserver;Username=sa;Password=P@ssw0rd;Database=identity" + } +} +``` + +2. Using MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseNpgsql()); +``` + +##### Usage 2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseNpgsql("Host=myserver;Username=sa;Password=P@ssw0rd;Database=identity")); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.zh-CN.md new file mode 100644 index 000000000..41aa6ad39 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.zh-CN.md @@ -0,0 +1,33 @@ +中 | [EN](README.md) + +## Masa.Contrib.Data.EntityFrameworkCore.PostgreSql + +## 用例: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.PostgreSql +``` + +#### 用法1: + +1. 配置appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "Host=myserver;Username=sa;Password=P@ssw0rd;Database=identity" + } +} +``` + +2. 使用MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseNpgsql()); +``` + +#### 用法2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseNpgsql("Host=myserver;Username=sa;Password=P@ssw0rd;Database=identity")); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/_Imports.cs new file mode 100644 index 000000000..4669c3de0 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/_Imports.cs @@ -0,0 +1,8 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Data; +global using Microsoft.EntityFrameworkCore; +global using Microsoft.Extensions.DependencyInjection; +global using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure; +global using System.Data.Common; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/Masa.Contrib.Data.EntityFrameworkCore.SqlServer.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/Masa.Contrib.Data.EntityFrameworkCore.SqlServer.csproj new file mode 100644 index 000000000..27db5063b --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/Masa.Contrib.Data.EntityFrameworkCore.SqlServer.csproj @@ -0,0 +1,18 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/MasaDbContextOptionsBuilderExtensions.cs new file mode 100644 index 000000000..c7bd12452 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/MasaDbContextOptionsBuilderExtensions.cs @@ -0,0 +1,33 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.SqlServer; + +public static class MasaDbContextOptionsBuilderExtensions +{ + public static MasaDbContextOptionsBuilder UseSqlServer( + this MasaDbContextOptionsBuilder builder, + Action? sqlServerOptionsAction = null) + { + var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); + return builder.UseSqlServer(connectionStringProvider.GetConnectionString(), sqlServerOptionsAction); + } + + public static MasaDbContextOptionsBuilder UseSqlServer( + this MasaDbContextOptionsBuilder builder, + string connectionString, + Action? sqlServerOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseSqlServer(connectionString, sqlServerOptionsAction); + return builder; + } + + public static MasaDbContextOptionsBuilder UseSqlServer( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + Action? sqlServerOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseSqlServer(connection, sqlServerOptionsAction); + return builder; + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.md new file mode 100644 index 000000000..68d1af184 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.md @@ -0,0 +1,33 @@ +[中](README.zh-CN.md) | EN + +## Masa.Contrib.Data.EntityFrameworkCore.SqlServer + +## Example: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.SqlServer +``` + +##### Usage 1: + +1. Configure appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "server=localhost;uid=sa;pwd=P@ssw0rd;database=identity" + } +} +``` + +2. Using MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlServer()); +``` + +##### Usage 2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlServer("server=localhost;uid=sa;pwd=P@ssw0rd;database=identity")); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.zh-CN.md new file mode 100644 index 000000000..9df34a017 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.zh-CN.md @@ -0,0 +1,33 @@ +中 | [EN](README.md) + +## Masa.Contrib.Data.EntityFrameworkCore.SqlServer + +## 用例: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.SqlServer +``` + +#### 用法1: + +1. 配置appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "server=localhost;uid=sa;pwd=P@ssw0rd;database=identity" + } +} +``` + +2. 使用MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlServer()); +``` + +#### 用法2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlServer("server=localhost;uid=sa;pwd=P@ssw0rd;database=identity")); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/_Imports.cs new file mode 100644 index 000000000..6c838c511 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/_Imports.cs @@ -0,0 +1,8 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Data; +global using Microsoft.EntityFrameworkCore; +global using Microsoft.EntityFrameworkCore.Infrastructure; +global using Microsoft.Extensions.DependencyInjection; +global using System.Data.Common; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/Masa.Contrib.Data.EntityFrameworkCore.Sqlite.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/Masa.Contrib.Data.EntityFrameworkCore.Sqlite.csproj new file mode 100644 index 000000000..ea92032eb --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/Masa.Contrib.Data.EntityFrameworkCore.Sqlite.csproj @@ -0,0 +1,18 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/MasaDbContextOptionsBuilderExtensions.cs new file mode 100644 index 000000000..9d326a34c --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/MasaDbContextOptionsBuilderExtensions.cs @@ -0,0 +1,33 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Sqlite; + +public static class MasaDbContextOptionsBuilderExtensions +{ + public static MasaDbContextOptionsBuilder UseSqlite( + this MasaDbContextOptionsBuilder builder, + Action? sqliteOptionsAction = null) + { + var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); + return builder.UseSqlite(connectionStringProvider.GetConnectionString(), sqliteOptionsAction); + } + + public static MasaDbContextOptionsBuilder UseSqlite( + this MasaDbContextOptionsBuilder builder, + string connectionString, + Action? sqliteOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseSqlite(connectionString, sqliteOptionsAction); + return builder; + } + + public static MasaDbContextOptionsBuilder UseSqlite( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + Action? sqliteOptionsAction = null) + { + builder.DbContextOptionsBuilder.UseSqlite(connection, sqliteOptionsAction); + return builder; + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.md new file mode 100644 index 000000000..5275a936f --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.md @@ -0,0 +1,33 @@ +[中](README.zh-CN.md) | EN + +## Masa.Contrib.Data.EntityFrameworkCore.Sqlite + +## Example: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.Sqlite +``` + +##### Usage 1: + +1. Configure appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "Data Source=c:\mydb.db;Version=3;Password=P@ssw0rd;" + } +} +``` + +2. Using MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlite()); +``` + +##### Usage 2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlite("Data Source=c:\mydb.db;Version=3;Password=P@ssw0rd;")); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.zh-CN.md new file mode 100644 index 000000000..372101b81 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.zh-CN.md @@ -0,0 +1,33 @@ +中 | [EN](README.md) + +## Masa.Contrib.Data.EntityFrameworkCore.Sqlite + +## 用例: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore.Sqlite +``` + +#### 用法1: + +1. 配置appsettings.json + +``` appsettings.json +{ + "ConnectionStrings": { + "DefaultConnection": "Data Source=c:\mydb.db;Version=3;Password=P@ssw0rd;" + } +} +``` + +2. 使用MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlite()); +``` + +#### 用法2: + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlite("Data Source=c:\mydb.db;Version=3;Password=P@ssw0rd;")); +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/_Imports.cs new file mode 100644 index 000000000..6c838c511 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/_Imports.cs @@ -0,0 +1,8 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Data; +global using Microsoft.EntityFrameworkCore; +global using Microsoft.EntityFrameworkCore.Infrastructure; +global using Microsoft.Extensions.DependencyInjection; +global using System.Data.Common; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/DefaultConnectionStringProvider.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/DefaultConnectionStringProvider.cs new file mode 100644 index 000000000..bd821626c --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/DefaultConnectionStringProvider.cs @@ -0,0 +1,14 @@ +using Masa.BuildingBlocks.Data; + +namespace Masa.Contrib.Data.EntityFrameworkCore; + +public class DefaultConnectionStringProvider : IConnectionStringProvider +{ + private readonly IOptionsSnapshot _options; + + public DefaultConnectionStringProvider(IOptionsSnapshot options) => _options = options; + + public Task GetConnectionStringAsync() => Task.FromResult(GetConnectionString()); + + public string GetConnectionString() => _options.Value.DefaultConnection; +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/ISaveChangesFilter.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/ISaveChangesFilter.cs new file mode 100644 index 000000000..27485faf9 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/ISaveChangesFilter.cs @@ -0,0 +1,6 @@ +namespace Masa.Contrib.Data.EntityFrameworkCore.Filters; + +public interface ISaveChangesFilter +{ + void OnExecuting(ChangeTracker changeTracker); +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/SoftDeleteSaveChangesFilter.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/SoftDeleteSaveChangesFilter.cs new file mode 100644 index 000000000..e9f2b9a6c --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/SoftDeleteSaveChangesFilter.cs @@ -0,0 +1,65 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Filters; + +public class SoftDeleteSaveChangesFilter : ISaveChangesFilter where TDbContext : DbContext +{ + private readonly TDbContext _context; + private readonly MasaDbContextOptions _masaDbContextOptions; + + public SoftDeleteSaveChangesFilter(MasaDbContextOptions masaDbContextOptions, TDbContext dbContext) + { + _masaDbContextOptions = masaDbContextOptions; + _context = dbContext; + } + + public void OnExecuting(ChangeTracker changeTracker) + { + if (!_masaDbContextOptions.EnableSoftDelete) + return; + + changeTracker.DetectChanges(); + foreach (var entity in changeTracker.Entries().Where(entry => entry.State == EntityState.Deleted)) + { + if (entity.Entity is ISoftDelete) + { + HandleNavigationEntry(entity.Navigations.Where(n => !((IReadOnlyNavigation)n.Metadata).IsOnDependent)); + + entity.State = EntityState.Modified; + entity.CurrentValues[nameof(ISoftDelete.IsDeleted)] = true; + } + } + } + + protected virtual void HandleNavigationEntry(IEnumerable navigationEntries) + { + foreach (var navigationEntry in navigationEntries) + { + if (navigationEntry is CollectionEntry collectionEntry) + { + foreach (var dependentEntry in collectionEntry.CurrentValue ?? new List()) + { + HandleDependent(dependentEntry); + } + } + else + { + var dependentEntry = navigationEntry.CurrentValue; + if (dependentEntry != null) + { + HandleDependent(dependentEntry); + } + } + } + } + + protected virtual void HandleDependent(object dependentEntry) + { + var entityEntry = _context.Entry(dependentEntry); + entityEntry.State = EntityState.Modified; + + if (entityEntry.Entity is ISoftDelete) + entityEntry.CurrentValues[nameof(ISoftDelete.IsDeleted)] = true; + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/IModelCreatingProvider.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/IModelCreatingProvider.cs new file mode 100644 index 000000000..b7e07c17f --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/IModelCreatingProvider.cs @@ -0,0 +1,10 @@ +namespace Masa.Contrib.Data.EntityFrameworkCore; + +public interface IModelCreatingProvider +{ + /// + /// + /// + /// + void Configure(ModelBuilder modelBuilder); +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Internal/Const.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Internal/Const.cs new file mode 100644 index 000000000..8b0d21e2b --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Internal/Const.cs @@ -0,0 +1,9 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Internal; + +internal class Const +{ + public const string DEFAULT_SECTION = "ConnectionStrings"; +} diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/Masa.Contrib.Data.Contracts.EF.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Contrib.Data.EntityFrameworkCore.csproj similarity index 50% rename from src/Data/Masa.Contrib.Data.Contracts.EF/Masa.Contrib.Data.Contracts.EF.csproj rename to src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Contrib.Data.EntityFrameworkCore.csproj index 9878dff58..5c3a7d0cc 100644 --- a/src/Data/Masa.Contrib.Data.Contracts.EF/Masa.Contrib.Data.Contracts.EF.csproj +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Contrib.Data.EntityFrameworkCore.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -7,13 +7,19 @@ - - + + - + - + + + + + + + diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Utils.Data.EntityFrameworkCore.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Utils.Data.EntityFrameworkCore.csproj new file mode 100644 index 000000000..efd5302c9 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Utils.Data.EntityFrameworkCore.csproj @@ -0,0 +1,15 @@ + + + + net6.0 + enable + enable + + + + + + + + + diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbConnectionOptions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbConnectionOptions.cs new file mode 100644 index 000000000..558f032e1 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbConnectionOptions.cs @@ -0,0 +1,6 @@ +namespace Masa.Contrib.Data.EntityFrameworkCore; + +public class MasaDbConnectionOptions +{ + public string DefaultConnection { get; set; } = default!; +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContext.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContext.cs new file mode 100644 index 000000000..ffb3fb9f9 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContext.cs @@ -0,0 +1,133 @@ +namespace Masa.Contrib.Data.EntityFrameworkCore; + +public abstract class MasaDbContext : DbContext +{ + protected readonly IDataFilter? DataFilter; + protected readonly MasaDbContextOptions? Options; + + public MasaDbContext(MasaDbContextOptions options) : base(options) + { + Options = options; + DataFilter = options.ServiceProvider.GetService(); + } + + /// + /// Automatic filter soft delete data. + /// When you override this method,you should call base.. + /// + /// + /// + protected sealed override void OnModelCreating(ModelBuilder modelBuilder) + { + OnModelCreatingExecuting(modelBuilder); + + OnModelCreatingConfigureGlobalFilters(modelBuilder); + + // null when run dotnet ef cli + if (Options == null) + { + base.OnModelCreating(modelBuilder); + return; + } + + foreach (var provider in Options.ModelCreatingProviders) + provider.Configure(modelBuilder); + } + + /// + /// Use this method instead of OnModelCreating + /// + /// + protected virtual void OnModelCreatingExecuting(ModelBuilder modelBuilder) + { + + } + + protected virtual void OnModelCreatingConfigureGlobalFilters(ModelBuilder modelBuilder) + { + var methodInfo = typeof(MasaDbContext).GetMethod(nameof(ConfigureGlobalFilters), BindingFlags.NonPublic | BindingFlags.Instance); + + foreach (var entityType in modelBuilder.Model.GetEntityTypes()) + { + methodInfo!.MakeGenericMethod(entityType.ClrType).Invoke(this, new object?[] { modelBuilder, entityType }); + } + } + + protected virtual void ConfigureGlobalFilters(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) + where TEntity : class + { + if (mutableEntityType.BaseType == null) + { + var filterExpression = CreateFilterExpression(); + if (filterExpression != null) + modelBuilder.Entity().HasQueryFilter(filterExpression); + } + } + + protected virtual Expression>? CreateFilterExpression() + where TEntity : class + { + Expression>? expression = null; + + if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) + { + expression = entity => !IsSoftDeleteFilterEnabled || !EF.Property(entity, nameof(ISoftDelete.IsDeleted)); + } + + return expression; + } + + protected virtual bool IsSoftDeleteFilterEnabled => (Options?.EnableSoftDelete ?? false) && (DataFilter?.IsEnabled() ?? false); + + /// + /// Automatic soft delete. + /// + /// + /// + public override int SaveChanges() => SaveChanges(true); + + public sealed override int SaveChanges(bool acceptAllChangesOnSuccess) + { + OnBeforeSaveChanges(); + return base.SaveChanges(acceptAllChangesOnSuccess); + } + + protected virtual void OnBeforeSaveChanges() + { + if (Options != null) + { + foreach (var filter in Options.SaveChangesFilters) + { + try + { + filter.OnExecuting(ChangeTracker); + } + catch (Exception ex) + { + throw new Exception("An error occured when intercept SaveChanges() or SaveChangesAsync()()", ex); + } + } + } + } + + /// + /// Automatic soft delete. + /// + /// + /// + /// + public override Task SaveChangesAsync(CancellationToken cancellationToken = default) => SaveChangesAsync(true, cancellationToken); + + /// + /// Automatic soft delete. + /// + /// + /// + /// + /// + public sealed override Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default) + { + OnBeforeSaveChanges(); + return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken); + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions.cs new file mode 100644 index 000000000..f6560a3fa --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions.cs @@ -0,0 +1,21 @@ +namespace Masa.Contrib.Data.EntityFrameworkCore; + +public abstract class MasaDbContextOptions : DbContextOptions +{ + public readonly IServiceProvider ServiceProvider; + + public abstract IEnumerable ModelCreatingProviders { get; } + + /// + /// Can be used to intercept SaveChanges(Async) method + /// + public abstract IEnumerable SaveChangesFilters { get; } + + public bool EnableSoftDelete { get; } + + protected MasaDbContextOptions(IServiceProvider serviceProvider, bool enableSoftDelete) + { + ServiceProvider = serviceProvider; + EnableSoftDelete = enableSoftDelete; + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder.cs new file mode 100644 index 000000000..91394018b --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder.cs @@ -0,0 +1,23 @@ +namespace Masa.Contrib.Data.EntityFrameworkCore; + +public abstract class MasaDbContextOptionsBuilder +{ + public DbContextOptionsBuilder DbContextOptionsBuilder; + + public IServiceProvider ServiceProvider { get; } + + internal bool EnableSoftDelete { get; private set; } + + protected MasaDbContextOptionsBuilder(IServiceProvider serviceProvider, DbContextOptions options, bool enableSoftDelete) + { + DbContextOptionsBuilder = new DbContextOptionsBuilder(options); + ServiceProvider = serviceProvider; + EnableSoftDelete = enableSoftDelete; + } + + public MasaDbContextOptionsBuilder UseSoftDelete() + { + EnableSoftDelete = true; + return this; + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder`.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder`.cs new file mode 100644 index 000000000..00291e4e1 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder`.cs @@ -0,0 +1,9 @@ +namespace Masa.Contrib.Data.EntityFrameworkCore; + +public class MasaDbContextOptionsBuilder : MasaDbContextOptionsBuilder + where TContext : MasaDbContext +{ + public MasaDbContextOptionsBuilder(IServiceProvider serviceProvider) : base(serviceProvider, new DbContextOptions(), false) + { + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions`.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions`.cs new file mode 100644 index 000000000..a19a074b2 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions`.cs @@ -0,0 +1,81 @@ +namespace Masa.Contrib.Data.EntityFrameworkCore; + +public class MasaDbContextOptions : MasaDbContextOptions + where TContext : DbContext +{ + private readonly DbContextOptions _originOptions; + + public MasaDbContextOptions( + IServiceProvider serviceProvider, + DbContextOptions originOptions, + bool enableSoftDelete) : base(serviceProvider, enableSoftDelete) => _originOptions = originOptions; + + private IEnumerable? _modelCreatingProviders; + + /// + /// Can be used to filter data + /// + public override IEnumerable ModelCreatingProviders => _modelCreatingProviders ??= ServiceProvider.GetServices(); + + + private IEnumerable? _saveChangesFilters; + + /// + /// Can be used to intercept SaveChanges(Async) method + /// + public override IEnumerable SaveChangesFilters => _saveChangesFilters ??= ServiceProvider.GetServices(); + + /// + /// + /// + public override Type ContextType => _originOptions.ContextType; + + /// + /// + /// + public override bool IsFrozen => _originOptions.IsFrozen; + + /// + /// + /// + public override IEnumerable Extensions => _originOptions.Extensions; + + /// + /// + /// + /// + /// + /// + public override DbContextOptions WithExtension(TExtension extension) + { + return _originOptions.WithExtension(extension); + } + + /// + /// + /// + /// + /// + public override TExtension FindExtension() + { + return _originOptions.GetExtension(); + } + + /// + /// + /// + public override void Freeze() + { + _originOptions.Freeze(); + } + + /// + /// + /// + /// + /// + public override TExtension GetExtension() + { + return _originOptions.GetExtension(); + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.md new file mode 100644 index 000000000..bc2f5ea70 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.md @@ -0,0 +1,47 @@ +[中](README.zh-CN.md) | EN + +## Masa.Utils.Data.EntityFrameworkCore + +## Example: + +```c# +Install-Package Masa.Utils.Data.EntityFrameworkCore +Install-Package Microsoft.EntityFrameworkCore.SqlServer +``` + +#### Basic usage: + +Using MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => +{ + optionsBuilder.UseSoftDelete();//enable soft delete + optionsBuilder.DbContextOptionsBuilder.UseSqlServer("server=localhost;uid=sa;pwd=P@ssw0rd;database=identity"); +}); +``` + +Recommended usage: + +- [SqlServer](../Masa.Utils.Data.EntityFrameworkCore.SqlServer/README.md) +- [MySql](../Masa.Utils.Data.EntityFrameworkCore.MySql/README.md) +- [Pomelo.MySql](../Masa.Utils.Data.EntityFrameworkCore.Pomelo.MySql/README.md) +- [Sqlite](../Masa.Utils.Data.EntityFrameworkCore.Sqlite/README.md) +- [Cosmos](../Masa.Utils.Data.EntityFrameworkCore.Cosmos/README.md) +- [InMemory](../Masa.Utils.Data.EntityFrameworkCore.InMemory/README.md) +- [Oracle](../Masa.Utils.Data.EntityFrameworkCore.Oracle/README.md) +- [PostgreSql](../Masa.Utils.Data.EntityFrameworkCore.PostgreSql/README.md) + +#### data filter + +``` C# +public async Task GetAllAsync([FromServices] IRepository repository, [FromServices] IDataFilter dataFilter) +{ + // Temporarily disable soft delete filtering + using (dataFilter.Disable()) + { + var list = (await repository.GetListAsync()).ToList(); + return System.Text.Json.JsonSerializer.Serialize(list); + } +} +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.zh-CN.md new file mode 100644 index 000000000..d93d777cd --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.zh-CN.md @@ -0,0 +1,47 @@ +中 | [EN](README.md) + +## Masa.Utils.Data.EntityFrameworkCore + +## 用例: + +```c# +Install-Package Masa.Contrib.Data.EntityFrameworkCore +Install-Package Microsoft.EntityFrameworkCore.SqlServer//这里以SqlServer举例 +``` + +#### 基本用法: + +使用MasaDbContext + +``` C# +builder.Services.AddMasaDbContext(optionsBuilder => +{ + optionsBuilder.UseSoftDelete();//启用软删除 + optionsBuilder.DbContextOptionsBuilder.UseSqlServer("server=localhost;uid=sa;pwd=P@ssw0rd;database=identity"); +}); +``` + +推荐用法: + +- [SqlServer](../Masa.Utils.Data.EntityFrameworkCore.SqlServer/README.zh-CN.md) +- [MySql](../Masa.Utils.Data.EntityFrameworkCore.MySql/README.zh-CN.md) +- [Pomelo.MySql](../Masa.Utils.Data.EntityFrameworkCore.Pomelo.MySql/README.zh-CN.md) +- [Sqlite](../Masa.Utils.Data.EntityFrameworkCore.Sqlite/README.zh-CN.md) +- [Cosmos](../Masa.Utils.Data.EntityFrameworkCore.Cosmos/README.zh-CN.md) +- [InMemory](../Masa.Utils.Data.EntityFrameworkCore.InMemory/README.zh-CN.md) +- [Oracle](../Masa.Utils.Data.EntityFrameworkCore.Oracle/README.zh-CN.md) +- [PostgreSql](../Masa.Utils.Data.EntityFrameworkCore.PostgreSql/README.zh-CN.md) + +#### 数据过滤器 + +``` C# +public async Task GetAllAsync([FromServices] IRepository repository, [FromServices] IDataFilter dataFilter) +{ + // 临时禁用软删除过滤 + using (dataFilter.Disable()) + { + var list = (await repository.GetListAsync()).ToList(); + return System.Text.Json.JsonSerializer.Serialize(list); + } +} +``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/ServiceCollectionExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/ServiceCollectionExtensions.cs new file mode 100644 index 000000000..5777aaa4e --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/ServiceCollectionExtensions.cs @@ -0,0 +1,94 @@ +using Masa.BuildingBlocks.Data; + +namespace Masa.Contrib.Data.EntityFrameworkCore; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddMasaDbContext( + this IServiceCollection services, + Action? optionsBuilder = null, + ServiceLifetime contextLifetime = ServiceLifetime.Scoped, + ServiceLifetime optionsLifetime = ServiceLifetime.Scoped) + where TDbContext : MasaDbContext + => services.AddMasaDbContext( + (_, masaDbContextOptionsBuilder) => optionsBuilder?.Invoke(masaDbContextOptionsBuilder), + contextLifetime, + optionsLifetime); + + public static IServiceCollection AddMasaDbContext( + this IServiceCollection services, + Action? optionsBuilder = null, + ServiceLifetime contextLifetime = ServiceLifetime.Scoped, + ServiceLifetime optionsLifetime = ServiceLifetime.Scoped) + where TDbContext : MasaDbContext + => services + .AddDbContext(contextLifetime, optionsLifetime) + .AddCoreServices(optionsBuilder, optionsLifetime); + + private static IServiceCollection AddCoreServices( + this IServiceCollection services, + Action? optionsBuilder, + ServiceLifetime optionsLifetime) + where TDbContextImplementation : MasaDbContext + { + services.TryAddConfigure(); + services.TryAddScoped(); + services.TryAddScoped(typeof(DataFilter<>)); + services.TryAddScoped(); + services.TryAddEnumerable(new ServiceDescriptor(typeof(ISaveChangesFilter), typeof(SoftDeleteSaveChangesFilter), + ServiceLifetime.Scoped)); + + services.TryAdd( + new ServiceDescriptor( + typeof(MasaDbContextOptions), + serviceProvider => CreateMasaDbContextOptions(serviceProvider, optionsBuilder), + optionsLifetime)); + + services.Add( + new ServiceDescriptor( + typeof(MasaDbContextOptions), + serviceProvider => serviceProvider.GetRequiredService>(), + optionsLifetime)); + return services; + } + + private static MasaDbContextOptions CreateMasaDbContextOptions( + IServiceProvider serviceProvider, + Action? optionsBuilder) + where TDbContext : MasaDbContext + { + var masaDbContextOptionsBuilder = new MasaDbContextOptionsBuilder(serviceProvider); + optionsBuilder?.Invoke(serviceProvider, masaDbContextOptionsBuilder); + + return CreateMasaDbContextOptions( + serviceProvider, + masaDbContextOptionsBuilder.DbContextOptionsBuilder.Options, + masaDbContextOptionsBuilder.EnableSoftDelete); + } + + private static MasaDbContextOptions CreateMasaDbContextOptions(IServiceProvider serviceProvider, + DbContextOptions options, bool enableSoftDelete) where TDbContext : MasaDbContext => new(serviceProvider, options, enableSoftDelete); + + private static IServiceCollection TryAddConfigure( + this IServiceCollection services) + where TOptions : class + => services.TryAddConfigure(Const.DEFAULT_SECTION); + + private static IServiceCollection TryAddConfigure( + this IServiceCollection services, + string sectionName) + where TOptions : class + { + IConfiguration? configuration = services.BuildServiceProvider().GetService(); + if (configuration == null) + return services; + + string name = Options.DefaultName; + services.AddOptions(); + var configurationSection = configuration.GetSection(sectionName); + services.TryAddSingleton>( + new ConfigurationChangeTokenSource(name, configurationSection)); + services.TryAddSingleton>(new NamedConfigureFromConfigurationOptions(name, configurationSection, _ => { })); + return services; + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/_Imports.cs new file mode 100644 index 000000000..0e887ef58 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/_Imports.cs @@ -0,0 +1,13 @@ +global using Microsoft.EntityFrameworkCore; +global using Microsoft.Extensions.Options; +global using Masa.BuildingBlocks.Data.Contracts.DataFiltering; +global using Microsoft.EntityFrameworkCore.Infrastructure; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.EntityFrameworkCore.ChangeTracking; +global using Masa.Contrib.Data.EntityFrameworkCore.Filters; +global using System.Linq.Expressions; +global using System.Reflection; +global using Microsoft.EntityFrameworkCore.Metadata; +global using Masa.Contrib.Data.EntityFrameworkCore.Internal; +global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.DependencyInjection.Extensions; From 571f8a4a27eb0f3871dc552c164888bbd8d43f76 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Sat, 7 May 2022 18:21:54 +0800 Subject: [PATCH 02/10] refactor(Data): Refactoring soft delete related functions --- Masa.Contrib.sln | 2 +- src/BuildingBlocks/MASA.BuildingBlocks | 2 +- .../Filters/SoftDeleteSaveChangesFilter.cs | 6 +- .../Internal/InstanceBuilder.cs | 27 ++++ .../Masa.Contrib.Data.Contracts.EF.csproj} | 1 + .../MasaDbContextOptionsBuilderExtensions.cs | 51 +++++++ .../Options/FilterOptions.cs | 15 ++ .../_Imports.cs | 16 ++ .../Masa.Contrib.Data.Contracts/_Imports.cs | 6 - .../MasaDbContextOptionsBuilderExtensions.cs | 47 ++++-- .../_Imports.cs | 2 + ...b.Data.EntityFrameworkCore.InMemory.csproj | 1 - .../MasaDbContextOptionsBuilderExtensions.cs | 23 ++- .../_Imports.cs | 1 + ...trib.Data.EntityFrameworkCore.MySql.csproj | 1 - .../MasaDbContextOptionsBuilderExtensions.cs | 26 +++- .../_Imports.cs | 1 + ...rib.Data.EntityFrameworkCore.Oracle.csproj | 1 - .../MasaDbContextOptionsBuilderExtensions.cs | 26 +++- .../_Imports.cs | 1 + ...ta.EntityFrameworkCore.Pomelo.MySql.csproj | 1 - .../MasaDbContextOptionsBuilderExtensions.cs | 27 +++- .../_Imports.cs | 1 + ...Data.EntityFrameworkCore.PostgreSql.csproj | 1 - .../MasaDbContextOptionsBuilderExtensions.cs | 26 +++- .../_Imports.cs | 1 + ....Data.EntityFrameworkCore.SqlServer.csproj | 1 - .../MasaDbContextOptionsBuilderExtensions.cs | 26 +++- .../_Imports.cs | 1 + ...rib.Data.EntityFrameworkCore.Sqlite.csproj | 1 - .../MasaDbContextOptionsBuilderExtensions.cs | 26 +++- .../_Imports.cs | 1 + .../DbConnectionStringProvider.cs | 10 +- .../DefaultConnectionStringProvider.cs | 16 +- .../EFDbContextOptionsBuilder.cs | 23 +++ .../EFDbContextOptionsBuilder`.cs | 10 ++ .../Filters/ISaveChangesFilter.cs | 2 +- .../Internal/Const.cs | 9 -- ...sa.Contrib.Data.EntityFrameworkCore.csproj | 6 +- .../MasaDbConnectionOptions.cs | 6 - .../MasaDbContext.cs | 23 ++- .../MasaDbContextOptionsBuilder.cs | 28 ++-- .../MasaDbContextOptionsBuilder`.cs | 9 -- .../ServiceCollectionExtensions.cs | 99 ++++++++----- .../_Imports.cs | 18 ++- .../DefaultConnectionStringProvider.cs | 13 +- .../DispatcherOptionsExtensions.cs | 42 +----- .../Masa.Contrib.Data.UoW.EF.csproj | 4 +- .../Masa.Contrib.Data.UoW.EF/UnitOfWork.cs | 2 +- .../UnitOfWorkAccessor.cs | 2 +- .../UnitOfWorkManager.cs | 4 +- src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs | 6 +- .../Repository.cs | 4 +- .../_Imports.cs | 1 + .../DispatcherOptionsExtensions.cs | 2 +- ...cher.IntegrationEvents.EventLogs.EF.csproj | 2 +- .../_Imports.cs | 3 +- .../DefaultConnectionStringProvider.cs | 16 -- .../DispatcherOptionsExtensions.cs | 24 +-- .../IsolationDbContext.cs | 18 +++ .../Masa.Contrib.Isolation.UoW.EF/_Imports.cs | 5 +- ...efaultIsolationConnectionStringProvider.cs | 36 +++-- .../DispatcherOptionsExtensions.cs | 24 +-- .../Masa.Contrib.Isolation/Internal/Const.cs | 9 -- .../IsolationDbContextProvider.cs | 6 +- .../Masa.Contrib.Isolation.csproj | 1 + .../Masa.Contrib.Isolation/_Imports.cs | 4 +- ...asa.Contrib.Data.Contracts.EF.Tests.csproj | 1 - .../Masa.Contrib.Data.UoW.EF.Tests.csproj | 2 +- .../TestUnitOfWork.cs | 8 +- .../_Imports.cs | 6 +- ...trib.Ddd.Domain.Repository.EF.Tests.csproj | 2 +- .../RepositoryTest.cs | 5 +- .../_Imports.cs | 4 +- .../ProcessorTest.cs | 16 +- .../_Imports.cs | 2 + ...ntegrationEvents.EventLogs.EF.Tests.csproj | 2 +- .../_Imports.cs | 4 +- ...TestDbIsolationConnectionStringProvider.cs | 138 +++++++++++------- .../TestIsolation.cs | 13 +- .../TestParserProvider.cs | 19 --- .../UnitOfWorkAccessor.cs | 2 + test/Masa.Contrib.Isolation.Tests/_Imports.cs | 4 +- ...Masa.Contrib.Isolation.UoW.EF.Tests.csproj | 2 +- .../TestIsolation.cs | 16 +- .../_Imports.cs | 5 +- ....Contrib.Isolation.UoW.EF.Web.Tests.csproj | 2 +- .../_Imports.cs | 7 +- 88 files changed, 711 insertions(+), 405 deletions(-) rename src/Data/{Masa.Contrib.Data.EntityFrameworkCore => Masa.Contrib.Data.Contracts.EF}/Filters/SoftDeleteSaveChangesFilter.cs (89%) create mode 100644 src/Data/Masa.Contrib.Data.Contracts.EF/Internal/InstanceBuilder.cs rename src/Data/{Masa.Contrib.Data.Contracts/Masa.Contrib.Data.Contracts.csproj => Masa.Contrib.Data.Contracts.EF/Masa.Contrib.Data.Contracts.EF.csproj} (81%) create mode 100644 src/Data/Masa.Contrib.Data.Contracts.EF/MasaDbContextOptionsBuilderExtensions.cs create mode 100644 src/Data/Masa.Contrib.Data.Contracts.EF/Options/FilterOptions.cs create mode 100644 src/Data/Masa.Contrib.Data.Contracts.EF/_Imports.cs delete mode 100644 src/Data/Masa.Contrib.Data.Contracts/_Imports.cs rename src/Data/{Masa.Contrib.Data.UoW.EF => Masa.Contrib.Data.EntityFrameworkCore}/DbConnectionStringProvider.cs (52%) create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder.cs create mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder`.cs delete mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/Internal/Const.cs delete mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbConnectionOptions.cs delete mode 100644 src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder`.cs delete mode 100644 src/Isolation/Masa.Contrib.Isolation.UoW.EF/DefaultConnectionStringProvider.cs delete mode 100644 src/Isolation/Masa.Contrib.Isolation/Internal/Const.cs diff --git a/Masa.Contrib.sln b/Masa.Contrib.sln index 0e9c65675..330fd1bbe 100644 --- a/Masa.Contrib.sln +++ b/Masa.Contrib.sln @@ -170,7 +170,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Storage", "Storage", "{1653 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Configuration.AutoMap.NoArgumentConstructor.Tests", "test\Masa.Contrib.Configuration.AutoMap.NoArgumentConstructor.Tests\Masa.Contrib.Configuration.AutoMap.NoArgumentConstructor.Tests.csproj", "{B8358ED1-C95A-4EC0-9756-FB32C931F204}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.Contracts", "src\Data\Masa.Contrib.Data.Contracts\Masa.Contrib.Data.Contracts.csproj", "{79D639DC-DDE4-45B1-884D-60B6908F528E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.Contracts.EF", "src\Data\Masa.Contrib.Data.Contracts.EF\Masa.Contrib.Data.Contracts.EF.csproj", "{79D639DC-DDE4-45B1-884D-60B6908F528E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Data", "src\BuildingBlocks\MASA.BuildingBlocks\src\Data\Masa.BuildingBlocks.Data\Masa.BuildingBlocks.Data.csproj", "{C3451307-3743-4911-A401-7F28889703D3}" EndProject diff --git a/src/BuildingBlocks/MASA.BuildingBlocks b/src/BuildingBlocks/MASA.BuildingBlocks index d0443a3b2..8803acefd 160000 --- a/src/BuildingBlocks/MASA.BuildingBlocks +++ b/src/BuildingBlocks/MASA.BuildingBlocks @@ -1 +1 @@ -Subproject commit d0443a3b2c1a82d1b2b4b4b3e6d163fb472f4960 +Subproject commit 8803acefd261479b142cbbef3f8a5b8f6c96b55a diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/SoftDeleteSaveChangesFilter.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/Filters/SoftDeleteSaveChangesFilter.cs similarity index 89% rename from src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/SoftDeleteSaveChangesFilter.cs rename to src/Data/Masa.Contrib.Data.Contracts.EF/Filters/SoftDeleteSaveChangesFilter.cs index e9f2b9a6c..138e43dbc 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/SoftDeleteSaveChangesFilter.cs +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/Filters/SoftDeleteSaveChangesFilter.cs @@ -1,14 +1,14 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Data.EntityFrameworkCore.Filters; +namespace Masa.Contrib.Data.Contracts.EF.Filters; public class SoftDeleteSaveChangesFilter : ISaveChangesFilter where TDbContext : DbContext { private readonly TDbContext _context; - private readonly MasaDbContextOptions _masaDbContextOptions; + private readonly MasaDbContextOptions _masaDbContextOptions; - public SoftDeleteSaveChangesFilter(MasaDbContextOptions masaDbContextOptions, TDbContext dbContext) + public SoftDeleteSaveChangesFilter(MasaDbContextOptions masaDbContextOptions, TDbContext dbContext) { _masaDbContextOptions = masaDbContextOptions; _context = dbContext; diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/InstanceBuilder.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/InstanceBuilder.cs new file mode 100644 index 000000000..170344c6b --- /dev/null +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/InstanceBuilder.cs @@ -0,0 +1,27 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.Contracts.EF.Internal; + +internal class InstanceBuilder +{ + internal delegate object InvokeDelegate(params object[] parameters); + + public static InvokeDelegate CreateInstanceDelegate(ConstructorInfo constructorInfo) + { + ParameterInfo[] parameters = constructorInfo.GetParameters(); + var parameterParameterExpression = Expression.Parameter(typeof(object[]), "parameters"); + + var parameterCast = new List(parameters.Length); + for (int i = 0; i < parameters.Length; i++) + { + var paramInfo = parameters[i]; + var valueObj = Expression.ArrayIndex(parameterParameterExpression, Expression.Constant(i)); + var valueCast = Expression.Convert(valueObj, paramInfo.ParameterType); + parameterCast.Add(valueCast); + } + NewExpression newExp = Expression.New(constructorInfo, parameterCast); + var lambdaExp = Expression.Lambda(newExp, parameterParameterExpression); + return lambdaExp.Compile(); + } +} diff --git a/src/Data/Masa.Contrib.Data.Contracts/Masa.Contrib.Data.Contracts.csproj b/src/Data/Masa.Contrib.Data.Contracts.EF/Masa.Contrib.Data.Contracts.EF.csproj similarity index 81% rename from src/Data/Masa.Contrib.Data.Contracts/Masa.Contrib.Data.Contracts.csproj rename to src/Data/Masa.Contrib.Data.Contracts.EF/Masa.Contrib.Data.Contracts.EF.csproj index 8bcb428a5..7cc463950 100644 --- a/src/Data/Masa.Contrib.Data.Contracts/Masa.Contrib.Data.Contracts.csproj +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/Masa.Contrib.Data.Contracts.EF.csproj @@ -8,6 +8,7 @@ + diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/MasaDbContextOptionsBuilderExtensions.cs new file mode 100644 index 000000000..d6df464cc --- /dev/null +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/MasaDbContextOptionsBuilderExtensions.cs @@ -0,0 +1,51 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.Contracts.EF; + +public static class MasaDbContextOptionsBuilderExtensions +{ + private static readonly List _types = new(); + + public static MasaDbContextOptionsBuilder UseFilter( + this MasaDbContextOptionsBuilder masaDbContextOptionsBuilder, + Action? options = null) + { + var filterOptions = new FilterOptions(); + options?.Invoke(filterOptions); + + masaDbContextOptionsBuilder.Services.TryAddScoped(typeof(DataFilter<>)); + masaDbContextOptionsBuilder.Services.TryAddScoped(); + + if (filterOptions.EnableSoftDelete) masaDbContextOptionsBuilder.UseSoftDelete(); + + return masaDbContextOptionsBuilder; + } + + private static void UseSoftDelete(this MasaDbContextOptionsBuilder masaDbContextOptionsBuilder) + { + if (_types.Any(type => masaDbContextOptionsBuilder.DbContextType == type)) + return; + + _types.Add(masaDbContextOptionsBuilder.DbContextType); + + var masaDbContextOptionsType = typeof(MasaDbContextOptions<>).MakeGenericType(masaDbContextOptionsBuilder.DbContextType); + var softDeleteSaveChangesFilterType = + typeof(SoftDeleteSaveChangesFilter<>).MakeGenericType(masaDbContextOptionsBuilder.DbContextType); + var constructorInfo = softDeleteSaveChangesFilterType.GetConstructors().FirstOrDefault()!; + var invokeDelegate = InstanceBuilder.CreateInstanceDelegate(constructorInfo); + + masaDbContextOptionsBuilder.Services.TryAdd( + new ServiceDescriptor(typeof(ISaveChangesFilter), + serviceProvider => + { + var instance= invokeDelegate.Invoke( + serviceProvider.GetRequiredService(masaDbContextOptionsType), + serviceProvider.GetRequiredService(masaDbContextOptionsBuilder.DbContextType)); + return instance; + }, + ServiceLifetime.Scoped)); + + masaDbContextOptionsBuilder.EnableSoftDelete = true; + } +} diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/Options/FilterOptions.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/Options/FilterOptions.cs new file mode 100644 index 000000000..43a11515d --- /dev/null +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/Options/FilterOptions.cs @@ -0,0 +1,15 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.Contracts.EF.Options; + +public class FilterOptions +{ + /// + /// enable soft delete + /// default: true + /// If you are sure that you do not need to use soft delete in the project, you can change to false + /// IDataFilter does not support ISoftDelete when soft delete is disabled + /// + public bool EnableSoftDelete { get; set; } = true; +} diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/_Imports.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/_Imports.cs new file mode 100644 index 000000000..82f53b576 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/_Imports.cs @@ -0,0 +1,16 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Data.Contracts.DataFiltering; +global using Masa.Contrib.Data.Contracts.EF.Filters; +global using Masa.Contrib.Data.Contracts.EF.Internal; +global using Masa.Contrib.Data.Contracts.EF.Options; +global using Masa.Contrib.Data.EntityFrameworkCore; +global using Masa.Contrib.Data.EntityFrameworkCore.Filters; +global using Microsoft.EntityFrameworkCore; +global using Microsoft.EntityFrameworkCore.ChangeTracking; +global using Microsoft.EntityFrameworkCore.Metadata; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.DependencyInjection.Extensions; +global using System.Linq.Expressions; +global using System.Reflection; diff --git a/src/Data/Masa.Contrib.Data.Contracts/_Imports.cs b/src/Data/Masa.Contrib.Data.Contracts/_Imports.cs deleted file mode 100644 index ec8f2bb57..000000000 --- a/src/Data/Masa.Contrib.Data.Contracts/_Imports.cs +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -global using System.Collections.Concurrent; -global using Masa.BuildingBlocks.Data.Contracts.DataFiltering; -global using Microsoft.Extensions.DependencyInjection; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/MasaDbContextOptionsBuilderExtensions.cs index c2e4f4835..a66edf49f 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/MasaDbContextOptionsBuilderExtensions.cs @@ -1,8 +1,6 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -using Masa.BuildingBlocks.Data; - namespace Masa.Contrib.Data.EntityFrameworkCore.Cosmos; public static class MasaDbContextOptionsBuilderExtensions @@ -11,20 +9,29 @@ public static MasaDbContextOptionsBuilder UseCosmos( this MasaDbContextOptionsBuilder builder, Action? cosmosOptionsAction = null) { - var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); - var configurationDic = connectionStringProvider.GetConnectionString().ToDictionary(); + builder.Builder = (serviceProvider, dbContextOptionsBuilder) => + { + var connectionStringProvider = serviceProvider.GetRequiredService(); + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + var configurationDic = connectionStringProvider.GetConnectionString(name).ToDictionary(); - if (!configurationDic.TryGetValue("Database", out string? databaseName)) - throw new ArgumentException("Cosmos: Bad database connection string, Failed to get [Database] name"); + if (!configurationDic.TryGetValue("Database", out string? databaseName)) + throw new ArgumentException("Cosmos: Bad database connection string, Failed to get [Database] name"); - if (configurationDic.TryGetValue("ConnectionString", out string? connectionString)) - return builder.UseCosmos(connectionString, databaseName, cosmosOptionsAction); + if (configurationDic.TryGetValue("ConnectionString", out string? connectionString)) + { + dbContextOptionsBuilder.UseCosmos(connectionString, databaseName, cosmosOptionsAction); + return; + } - if (!configurationDic.TryGetValue("AccountKey", out string? accountKey) || - !configurationDic.TryGetValue("AccountEndpoint", out string? accountEndpoint)) - throw new ArgumentException("Cosmos: Bad database connection string, Failed to get [AccountKey] name or [AccountEndpoint] name"); + if (!configurationDic.TryGetValue("AccountKey", out string? accountKey) || + !configurationDic.TryGetValue("AccountEndpoint", out string? accountEndpoint)) + throw new ArgumentException( + "Cosmos: Bad database connection string, Failed to get [AccountKey] name or [AccountEndpoint] name"); - return builder.UseCosmos(accountEndpoint, accountKey, databaseName, cosmosOptionsAction); + dbContextOptionsBuilder.UseCosmos(accountEndpoint, accountKey, databaseName, cosmosOptionsAction); + }; + return builder; } public static MasaDbContextOptionsBuilder UseCosmos( @@ -34,7 +41,9 @@ public static MasaDbContextOptionsBuilder UseCosmos( string databaseName, Action? cosmosOptionsAction = null) { - builder.DbContextOptionsBuilder.UseCosmos(accountEndpoint, accountKey, databaseName, cosmosOptionsAction); + builder.UseCosmosCore($"AccountEndpoint={accountEndpoint};AccountKey={accountKey};Database={databaseName};"); + builder.Builder = (_, dbContextOptionsBuilder) + => dbContextOptionsBuilder.UseCosmos(accountEndpoint, accountKey, databaseName, cosmosOptionsAction); return builder; } @@ -44,7 +53,17 @@ public static MasaDbContextOptionsBuilder UseCosmos( string databaseName, Action? cosmosOptionsAction = null) { - builder.DbContextOptionsBuilder.UseCosmos(connectionString, databaseName, cosmosOptionsAction); + builder.UseCosmosCore($"{connectionString};Database={databaseName};"); + builder.Builder = (_, dbContextOptionsBuilder) + => dbContextOptionsBuilder.UseCosmos(connectionString, databaseName, cosmosOptionsAction); + return builder; + } + + private static MasaDbContextOptionsBuilder UseCosmosCore(this MasaDbContextOptionsBuilder builder, string connectionString) + { + var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + dbConnectionOptions.TryAddConnectionString(name, connectionString); return builder; } } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/_Imports.cs index 65640bc1f..12126d9f4 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/_Imports.cs @@ -2,3 +2,5 @@ global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.Infrastructure; global using Microsoft.Extensions.DependencyInjection; +global using Masa.BuildingBlocks.Data; +global using Microsoft.Extensions.Options; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/Masa.Contrib.Data.EntityFrameworkCore.InMemory.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/Masa.Contrib.Data.EntityFrameworkCore.InMemory.csproj index 693d26f36..e459bfda5 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/Masa.Contrib.Data.EntityFrameworkCore.InMemory.csproj +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/Masa.Contrib.Data.EntityFrameworkCore.InMemory.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/MasaDbContextOptionsBuilderExtensions.cs index 2768c8bb3..d3dccb041 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/MasaDbContextOptionsBuilderExtensions.cs @@ -9,8 +9,15 @@ public static MasaDbContextOptionsBuilder UseInMemoryDatabase( this MasaDbContextOptionsBuilder builder, Action? inMemoryOptionsAction = null) { - var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); - return builder.UseInMemoryDatabase(connectionStringProvider.GetConnectionString(), inMemoryOptionsAction); + builder.Builder = (serviceProvider, dbContextOptionsBuilder) => + { + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + var connectionStringProvider = serviceProvider.GetRequiredService(); + dbContextOptionsBuilder.UseInMemoryDatabase( + connectionStringProvider.GetConnectionString(name), + inMemoryOptionsAction); + }; + return builder; } public static MasaDbContextOptionsBuilder UseInMemoryDatabase( @@ -18,7 +25,17 @@ public static MasaDbContextOptionsBuilder UseInMemoryDatabase( string databaseName, Action? inMemoryOptionsAction = null) { - builder.DbContextOptionsBuilder.UseInMemoryDatabase(databaseName, inMemoryOptionsAction); + builder.UseInMemoryDatabaseCore(databaseName); + builder.Builder = (_, dbContextOptionsBuilder) + => dbContextOptionsBuilder.UseInMemoryDatabase(databaseName, inMemoryOptionsAction); + return builder; + } + + private static MasaDbContextOptionsBuilder UseInMemoryDatabaseCore(this MasaDbContextOptionsBuilder builder, string databaseName) + { + var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + dbConnectionOptions.TryAddConnectionString(name, databaseName); return builder; } } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/_Imports.cs index 0c0403d0b..4ec3d59f9 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/_Imports.cs @@ -5,3 +5,4 @@ global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.Infrastructure; global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Options; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/Masa.Contrib.Data.EntityFrameworkCore.MySql.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/Masa.Contrib.Data.EntityFrameworkCore.MySql.csproj index 96a55bb18..b78b4b775 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/Masa.Contrib.Data.EntityFrameworkCore.MySql.csproj +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/Masa.Contrib.Data.EntityFrameworkCore.MySql.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/MasaDbContextOptionsBuilderExtensions.cs index f32e9e66a..39ead98cb 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/MasaDbContextOptionsBuilderExtensions.cs @@ -9,8 +9,15 @@ public static MasaDbContextOptionsBuilder UseMySQL( this MasaDbContextOptionsBuilder builder, Action? mySqlOptionsAction = null) { - var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); - return builder.UseMySQL(connectionStringProvider.GetConnectionString(), mySqlOptionsAction); + builder.Builder = (serviceProvider, dbContextOptionsBuilder) => + { + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + var connectionStringProvider = serviceProvider.GetRequiredService(); + dbContextOptionsBuilder.UseMySQL( + connectionStringProvider.GetConnectionString(name), + mySqlOptionsAction); + }; + return builder; } public static MasaDbContextOptionsBuilder UseMySQL( @@ -18,7 +25,9 @@ public static MasaDbContextOptionsBuilder UseMySQL( string connectionString, Action? mySqlOptionsAction = null) { - builder.DbContextOptionsBuilder.UseMySQL(connectionString, mySqlOptionsAction); + builder.UseMySQLCore(connectionString); + builder.Builder = (_, dbContextOptionsBuilder) + => dbContextOptionsBuilder.UseMySQL(connectionString, mySqlOptionsAction); return builder; } @@ -27,7 +36,16 @@ public static MasaDbContextOptionsBuilder UseMySQL( DbConnection connection, Action? mySqlOptionsAction = null) { - builder.DbContextOptionsBuilder.UseMySQL(connection, mySqlOptionsAction); + builder.UseMySQLCore(connection.ConnectionString); + builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseMySQL(connection, mySqlOptionsAction); + return builder; + } + + private static MasaDbContextOptionsBuilder UseMySQLCore(this MasaDbContextOptionsBuilder builder, string connectionString) + { + var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + dbConnectionOptions.TryAddConnectionString(name, connectionString); return builder; } } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/_Imports.cs index 8d90ceb61..bb60991d6 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/_Imports.cs @@ -6,3 +6,4 @@ global using Microsoft.Extensions.DependencyInjection; global using MySql.EntityFrameworkCore.Infrastructure; global using System.Data.Common; +global using Microsoft.Extensions.Options; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/Masa.Contrib.Data.EntityFrameworkCore.Oracle.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/Masa.Contrib.Data.EntityFrameworkCore.Oracle.csproj index 38d86a4c7..ef7797dc1 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/Masa.Contrib.Data.EntityFrameworkCore.Oracle.csproj +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/Masa.Contrib.Data.EntityFrameworkCore.Oracle.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/MasaDbContextOptionsBuilderExtensions.cs index 65c3560d8..2141360b4 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/MasaDbContextOptionsBuilderExtensions.cs @@ -9,8 +9,15 @@ public static MasaDbContextOptionsBuilder UseOracle( this MasaDbContextOptionsBuilder builder, Action? oracleOptionsAction = null) { - var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); - return builder.UseOracle(connectionStringProvider.GetConnectionString(), oracleOptionsAction); + builder.Builder = (serviceProvider, dbContextOptionsBuilder) => + { + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + var connectionStringProvider = serviceProvider.GetRequiredService(); + dbContextOptionsBuilder.UseOracle( + connectionStringProvider.GetConnectionString(name), + oracleOptionsAction); + }; + return builder; } public static MasaDbContextOptionsBuilder UseOracle( @@ -18,7 +25,9 @@ public static MasaDbContextOptionsBuilder UseOracle( string connectionString, Action? oracleOptionsAction = null) { - builder.DbContextOptionsBuilder.UseOracle(connectionString, oracleOptionsAction); + builder.UseOracleCore(connectionString); + builder.Builder = (_, dbContextOptionsBuilder) + => dbContextOptionsBuilder.UseOracle(connectionString, oracleOptionsAction); return builder; } @@ -27,7 +36,16 @@ public static MasaDbContextOptionsBuilder UseOracle( DbConnection connection, Action? oracleOptionsAction = null) { - builder.DbContextOptionsBuilder.UseOracle(connection, oracleOptionsAction); + builder.UseOracleCore(connection.ConnectionString); + builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseOracle(connection, oracleOptionsAction); + return builder; + } + + private static MasaDbContextOptionsBuilder UseOracleCore(this MasaDbContextOptionsBuilder builder, string connectionString) + { + var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + dbConnectionOptions.TryAddConnectionString(name, connectionString); return builder; } } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/_Imports.cs index cd83d66a6..130409b03 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/_Imports.cs @@ -6,3 +6,4 @@ global using Microsoft.Extensions.DependencyInjection; global using Oracle.EntityFrameworkCore.Infrastructure; global using System.Data.Common; +global using Microsoft.Extensions.Options; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql.csproj index 595de2cda..44591917a 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql.csproj +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/MasaDbContextOptionsBuilderExtensions.cs index 535816571..321bd5d19 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/MasaDbContextOptionsBuilderExtensions.cs @@ -10,8 +10,16 @@ public static MasaDbContextOptionsBuilder UseMySql( ServerVersion serverVersion, Action? mySqlOptionsAction = null) { - var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); - return builder.UseMySql(connectionStringProvider.GetConnectionString(), serverVersion, mySqlOptionsAction); + builder.Builder = (serviceProvider, dbContextOptionsBuilder) => + { + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + var connectionStringProvider = serviceProvider.GetRequiredService(); + dbContextOptionsBuilder.UseMySql( + connectionStringProvider.GetConnectionString(name), + serverVersion, + mySqlOptionsAction); + }; + return builder; } public static MasaDbContextOptionsBuilder UseMySql( @@ -20,7 +28,9 @@ public static MasaDbContextOptionsBuilder UseMySql( ServerVersion serverVersion, Action? mySqlOptionsAction = null) { - builder.DbContextOptionsBuilder.UseMySql(connectionString, serverVersion, mySqlOptionsAction); + builder.UseMySqlCore(connectionString); + builder.Builder = (_, dbContextOptionsBuilder) + => dbContextOptionsBuilder.UseMySql(connectionString, serverVersion, mySqlOptionsAction); return builder; } @@ -30,7 +40,16 @@ public static MasaDbContextOptionsBuilder UseMySql( ServerVersion serverVersion, Action? mySqlOptionsAction = null) { - builder.DbContextOptionsBuilder.UseMySql(connection, serverVersion, mySqlOptionsAction); + builder.UseMySqlCore(connection.ConnectionString); + builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseMySql(connection, serverVersion, mySqlOptionsAction); + return builder; + } + + private static MasaDbContextOptionsBuilder UseMySqlCore(this MasaDbContextOptionsBuilder builder, string connectionString) + { + var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + dbConnectionOptions.TryAddConnectionString(name, connectionString); return builder; } } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/_Imports.cs index 6c838c511..267a343b6 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/_Imports.cs @@ -6,3 +6,4 @@ global using Microsoft.EntityFrameworkCore.Infrastructure; global using Microsoft.Extensions.DependencyInjection; global using System.Data.Common; +global using Microsoft.Extensions.Options; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql.csproj index e44d41277..127784087 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql.csproj +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/MasaDbContextOptionsBuilderExtensions.cs index a5a2f3505..a501c20bb 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/MasaDbContextOptionsBuilderExtensions.cs @@ -9,8 +9,15 @@ public static MasaDbContextOptionsBuilder UseNpgsql( this MasaDbContextOptionsBuilder builder, Action? npgsqlOptionsAction = null) { - var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); - return builder.UseNpgsql(connectionStringProvider.GetConnectionString(), npgsqlOptionsAction); + builder.Builder = (serviceProvider, dbContextOptionsBuilder) => + { + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + var connectionStringProvider = serviceProvider.GetRequiredService(); + dbContextOptionsBuilder.UseNpgsql( + connectionStringProvider.GetConnectionString(name), + npgsqlOptionsAction); + }; + return builder; } public static MasaDbContextOptionsBuilder UseNpgsql( @@ -18,7 +25,9 @@ public static MasaDbContextOptionsBuilder UseNpgsql( string connectionString, Action? npgsqlOptionsAction = null) { - builder.DbContextOptionsBuilder.UseNpgsql(connectionString, npgsqlOptionsAction); + builder.UseNpgsqlCore(connectionString); + builder.Builder = (_, dbContextOptionsBuilder) + => dbContextOptionsBuilder.UseNpgsql(connectionString, npgsqlOptionsAction); return builder; } @@ -27,7 +36,16 @@ public static MasaDbContextOptionsBuilder UseNpgsql( DbConnection connection, Action? npgsqlOptionsAction = null) { - builder.DbContextOptionsBuilder.UseNpgsql(connection, npgsqlOptionsAction); + builder.UseNpgsqlCore(connection.ConnectionString); + builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseNpgsql(connection, npgsqlOptionsAction); + return builder; + } + + private static MasaDbContextOptionsBuilder UseNpgsqlCore(this MasaDbContextOptionsBuilder builder, string connectionString) + { + var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + dbConnectionOptions.TryAddConnectionString(name, connectionString); return builder; } } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/_Imports.cs index 4669c3de0..ca567546f 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/_Imports.cs @@ -6,3 +6,4 @@ global using Microsoft.Extensions.DependencyInjection; global using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure; global using System.Data.Common; +global using Microsoft.Extensions.Options; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/Masa.Contrib.Data.EntityFrameworkCore.SqlServer.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/Masa.Contrib.Data.EntityFrameworkCore.SqlServer.csproj index 27db5063b..d3de9d140 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/Masa.Contrib.Data.EntityFrameworkCore.SqlServer.csproj +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/Masa.Contrib.Data.EntityFrameworkCore.SqlServer.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/MasaDbContextOptionsBuilderExtensions.cs index c7bd12452..8a1521a3a 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/MasaDbContextOptionsBuilderExtensions.cs @@ -9,8 +9,15 @@ public static MasaDbContextOptionsBuilder UseSqlServer( this MasaDbContextOptionsBuilder builder, Action? sqlServerOptionsAction = null) { - var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); - return builder.UseSqlServer(connectionStringProvider.GetConnectionString(), sqlServerOptionsAction); + builder.Builder = (serviceProvider, dbContextOptionsBuilder) => + { + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + var connectionStringProvider = serviceProvider.GetRequiredService(); + dbContextOptionsBuilder.UseSqlServer( + connectionStringProvider.GetConnectionString(name), + sqlServerOptionsAction); + }; + return builder; } public static MasaDbContextOptionsBuilder UseSqlServer( @@ -18,7 +25,9 @@ public static MasaDbContextOptionsBuilder UseSqlServer( string connectionString, Action? sqlServerOptionsAction = null) { - builder.DbContextOptionsBuilder.UseSqlServer(connectionString, sqlServerOptionsAction); + builder.UseSqlServerCore(connectionString); + builder.Builder = (_, dbContextOptionsBuilder) + => dbContextOptionsBuilder.UseSqlServer(connectionString, sqlServerOptionsAction); return builder; } @@ -27,7 +36,16 @@ public static MasaDbContextOptionsBuilder UseSqlServer( DbConnection connection, Action? sqlServerOptionsAction = null) { - builder.DbContextOptionsBuilder.UseSqlServer(connection, sqlServerOptionsAction); + builder.UseSqlServerCore(connection.ConnectionString); + builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseSqlServer(connection, sqlServerOptionsAction); + return builder; + } + + private static MasaDbContextOptionsBuilder UseSqlServerCore(this MasaDbContextOptionsBuilder builder, string connectionString) + { + var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + dbConnectionOptions.TryAddConnectionString(name, connectionString); return builder; } } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/_Imports.cs index 6c838c511..267a343b6 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/_Imports.cs @@ -6,3 +6,4 @@ global using Microsoft.EntityFrameworkCore.Infrastructure; global using Microsoft.Extensions.DependencyInjection; global using System.Data.Common; +global using Microsoft.Extensions.Options; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/Masa.Contrib.Data.EntityFrameworkCore.Sqlite.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/Masa.Contrib.Data.EntityFrameworkCore.Sqlite.csproj index ea92032eb..ef57aefe8 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/Masa.Contrib.Data.EntityFrameworkCore.Sqlite.csproj +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/Masa.Contrib.Data.EntityFrameworkCore.Sqlite.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/MasaDbContextOptionsBuilderExtensions.cs index 9d326a34c..65e449027 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/MasaDbContextOptionsBuilderExtensions.cs @@ -9,8 +9,15 @@ public static MasaDbContextOptionsBuilder UseSqlite( this MasaDbContextOptionsBuilder builder, Action? sqliteOptionsAction = null) { - var connectionStringProvider = builder.ServiceProvider.GetRequiredService(); - return builder.UseSqlite(connectionStringProvider.GetConnectionString(), sqliteOptionsAction); + builder.Builder = (serviceProvider, dbContextOptionsBuilder) => + { + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + var connectionStringProvider = serviceProvider.GetRequiredService(); + dbContextOptionsBuilder.UseSqlite( + connectionStringProvider.GetConnectionString(name), + sqliteOptionsAction); + }; + return builder; } public static MasaDbContextOptionsBuilder UseSqlite( @@ -18,7 +25,9 @@ public static MasaDbContextOptionsBuilder UseSqlite( string connectionString, Action? sqliteOptionsAction = null) { - builder.DbContextOptionsBuilder.UseSqlite(connectionString, sqliteOptionsAction); + builder.UseSqliteCore(connectionString); + builder.Builder = (_, dbContextOptionsBuilder) + => dbContextOptionsBuilder.UseSqlite(connectionString, sqliteOptionsAction); return builder; } @@ -27,7 +36,16 @@ public static MasaDbContextOptionsBuilder UseSqlite( DbConnection connection, Action? sqliteOptionsAction = null) { - builder.DbContextOptionsBuilder.UseSqlite(connection, sqliteOptionsAction); + builder.UseSqliteCore(connection.ConnectionString); + builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseSqlite(connection, sqliteOptionsAction); + return builder; + } + + private static MasaDbContextOptionsBuilder UseSqliteCore(this MasaDbContextOptionsBuilder builder, string connectionString) + { + var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; + var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + dbConnectionOptions.TryAddConnectionString(name, connectionString); return builder; } } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/_Imports.cs index 6c838c511..267a343b6 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/_Imports.cs @@ -6,3 +6,4 @@ global using Microsoft.EntityFrameworkCore.Infrastructure; global using Microsoft.Extensions.DependencyInjection; global using System.Data.Common; +global using Microsoft.Extensions.Options; diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/DbConnectionStringProvider.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/DbConnectionStringProvider.cs similarity index 52% rename from src/Data/Masa.Contrib.Data.UoW.EF/DbConnectionStringProvider.cs rename to src/Data/Masa.Contrib.Data.EntityFrameworkCore/DbConnectionStringProvider.cs index de8408e60..243a36930 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/DbConnectionStringProvider.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/DbConnectionStringProvider.cs @@ -1,7 +1,7 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Data.UoW.EF; +namespace Masa.Contrib.Data.EntityFrameworkCore; public class DbConnectionStringProvider : BaseDbConnectionStringProvider { @@ -9,8 +9,6 @@ public class DbConnectionStringProvider : BaseDbConnectionStringProvider public DbConnectionStringProvider(IOptionsMonitor options) => _options = options; - protected override List GetDbContextOptionsList() - { - return new() { new(_options.CurrentValue.DefaultConnection) }; - } + protected override List GetDbContextOptionsList() + => _options.CurrentValue.ConnectionStrings.Select(item => new MasaDbContextConfigurationOptions(item.Value)).Distinct().ToList(); } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/DefaultConnectionStringProvider.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/DefaultConnectionStringProvider.cs index bd821626c..4ff366d62 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/DefaultConnectionStringProvider.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/DefaultConnectionStringProvider.cs @@ -1,14 +1,18 @@ -using Masa.BuildingBlocks.Data; - namespace Masa.Contrib.Data.EntityFrameworkCore; public class DefaultConnectionStringProvider : IConnectionStringProvider { - private readonly IOptionsSnapshot _options; + private readonly IOptionsMonitor _options; + + public DefaultConnectionStringProvider(IOptionsMonitor options) => _options = options; - public DefaultConnectionStringProvider(IOptionsSnapshot options) => _options = options; + public Task GetConnectionStringAsync(string name = ConnectionStrings.DEFAULT_CONNECTION_STRING_NAME) => Task.FromResult(GetConnectionString(name)); - public Task GetConnectionStringAsync() => Task.FromResult(GetConnectionString()); + public string GetConnectionString(string name = ConnectionStrings.DEFAULT_CONNECTION_STRING_NAME) + { + if (string.IsNullOrEmpty(name)) + return _options.CurrentValue.ConnectionStrings.DefaultConnection; - public string GetConnectionString() => _options.Value.DefaultConnection; + return _options.CurrentValue.ConnectionStrings.GetConnectionString(name); + } } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder.cs new file mode 100644 index 000000000..42c3cca74 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder.cs @@ -0,0 +1,23 @@ +namespace Masa.Contrib.Data.EntityFrameworkCore; + +public abstract class EFDbContextOptionsBuilder +{ + public readonly DbContextOptionsBuilder DbContextOptionsBuilder; + + public IServiceProvider ServiceProvider { get; } + + internal bool EnableSoftDelete { get; private set; } + + protected EFDbContextOptionsBuilder(IServiceProvider serviceProvider, DbContextOptions options, bool enableSoftDelete) + { + DbContextOptionsBuilder = new DbContextOptionsBuilder(options); + ServiceProvider = serviceProvider; + EnableSoftDelete = enableSoftDelete; + } + + public EFDbContextOptionsBuilder UseSoftDelete() + { + EnableSoftDelete = true; + return this; + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder`.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder`.cs new file mode 100644 index 000000000..4dc06bd75 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder`.cs @@ -0,0 +1,10 @@ +namespace Masa.Contrib.Data.EntityFrameworkCore; + +public class EFDbContextOptionsBuilder : EFDbContextOptionsBuilder + where TDbContext : MasaDbContext, IMasaDbContext +{ + public EFDbContextOptionsBuilder(IServiceProvider serviceProvider) + : base(serviceProvider, new DbContextOptions(), false) + { + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/ISaveChangesFilter.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/ISaveChangesFilter.cs index 27485faf9..f0e6380b4 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/ISaveChangesFilter.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/ISaveChangesFilter.cs @@ -1,4 +1,4 @@ -namespace Masa.Contrib.Data.EntityFrameworkCore.Filters; +namespace Masa.Contrib.Data.EntityFrameworkCore.Filters; public interface ISaveChangesFilter { diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Internal/Const.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Internal/Const.cs deleted file mode 100644 index 8b0d21e2b..000000000 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Internal/Const.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Data.EntityFrameworkCore.Internal; - -internal class Const -{ - public const string DEFAULT_SECTION = "ConnectionStrings"; -} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Contrib.Data.EntityFrameworkCore.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Contrib.Data.EntityFrameworkCore.csproj index 5c3a7d0cc..ca24e104f 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Contrib.Data.EntityFrameworkCore.csproj +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Contrib.Data.EntityFrameworkCore.csproj @@ -11,13 +11,13 @@ - + + - - + diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbConnectionOptions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbConnectionOptions.cs deleted file mode 100644 index 558f032e1..000000000 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbConnectionOptions.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Masa.Contrib.Data.EntityFrameworkCore; - -public class MasaDbConnectionOptions -{ - public string DefaultConnection { get; set; } = default!; -} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContext.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContext.cs index ffb3fb9f9..b20af47e8 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContext.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContext.cs @@ -1,6 +1,6 @@ namespace Masa.Contrib.Data.EntityFrameworkCore; -public abstract class MasaDbContext : DbContext +public abstract class MasaDbContext : DbContext, IMasaDbContext { protected readonly IDataFilter? DataFilter; protected readonly MasaDbContextOptions? Options; @@ -77,7 +77,8 @@ protected virtual void ConfigureGlobalFilters(ModelBuilder modelBuilder return expression; } - protected virtual bool IsSoftDeleteFilterEnabled => (Options?.EnableSoftDelete ?? false) && (DataFilter?.IsEnabled() ?? false); + protected virtual bool IsSoftDeleteFilterEnabled + => (Options?.EnableSoftDelete ?? false) && (DataFilter?.IsEnabled() ?? false); /// /// Automatic soft delete. @@ -131,3 +132,21 @@ public sealed override Task SaveChangesAsync(bool acceptAllChangesOnSuccess return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken); } } + +public abstract class MasaDbContext : MasaDbContext + where TDbContext : DbContext, IMasaDbContext +{ + public MasaDbContext(MasaDbContextOptions options) : base(options) + { + } + + protected override void OnModelCreatingConfigureGlobalFilters(ModelBuilder modelBuilder) + { + var methodInfo = typeof(MasaDbContext).GetMethod(nameof(ConfigureGlobalFilters), BindingFlags.NonPublic | BindingFlags.Instance); + + foreach (var entityType in modelBuilder.Model.GetEntityTypes()) + { + methodInfo!.MakeGenericMethod(entityType.ClrType).Invoke(this, new object?[] { modelBuilder, entityType }); + } + } +} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder.cs index 91394018b..98670b70d 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder.cs @@ -1,23 +1,25 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + namespace Masa.Contrib.Data.EntityFrameworkCore; -public abstract class MasaDbContextOptionsBuilder +public class MasaDbContextOptionsBuilder { - public DbContextOptionsBuilder DbContextOptionsBuilder; + private IServiceProvider? _serviceProvider; - public IServiceProvider ServiceProvider { get; } + public IServiceProvider ServiceProvider => _serviceProvider ??= Services.BuildServiceProvider(); - internal bool EnableSoftDelete { get; private set; } + public IServiceCollection Services { get; } - protected MasaDbContextOptionsBuilder(IServiceProvider serviceProvider, DbContextOptions options, bool enableSoftDelete) - { - DbContextOptionsBuilder = new DbContextOptionsBuilder(options); - ServiceProvider = serviceProvider; - EnableSoftDelete = enableSoftDelete; - } + public Type DbContextType { get; } + + public Action Builder { get; set; } = default!; + + public bool EnableSoftDelete { get; set; } - public MasaDbContextOptionsBuilder UseSoftDelete() + public MasaDbContextOptionsBuilder(IServiceCollection services, Type dbContextType) { - EnableSoftDelete = true; - return this; + Services = services; + DbContextType = dbContextType; } } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder`.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder`.cs deleted file mode 100644 index 00291e4e1..000000000 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder`.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Masa.Contrib.Data.EntityFrameworkCore; - -public class MasaDbContextOptionsBuilder : MasaDbContextOptionsBuilder - where TContext : MasaDbContext -{ - public MasaDbContextOptionsBuilder(IServiceProvider serviceProvider) : base(serviceProvider, new DbContextOptions(), false) - { - } -} diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/ServiceCollectionExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/ServiceCollectionExtensions.cs index 5777aaa4e..10fa218d5 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/ServiceCollectionExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/ServiceCollectionExtensions.cs @@ -1,42 +1,44 @@ -using Masa.BuildingBlocks.Data; - namespace Masa.Contrib.Data.EntityFrameworkCore; public static class ServiceCollectionExtensions { - public static IServiceCollection AddMasaDbContext( + public static IServiceCollection AddMasaDbContext( this IServiceCollection services, Action? optionsBuilder = null, ServiceLifetime contextLifetime = ServiceLifetime.Scoped, ServiceLifetime optionsLifetime = ServiceLifetime.Scoped) - where TDbContext : MasaDbContext - => services.AddMasaDbContext( - (_, masaDbContextOptionsBuilder) => optionsBuilder?.Invoke(masaDbContextOptionsBuilder), - contextLifetime, - optionsLifetime); - - public static IServiceCollection AddMasaDbContext( - this IServiceCollection services, - Action? optionsBuilder = null, - ServiceLifetime contextLifetime = ServiceLifetime.Scoped, - ServiceLifetime optionsLifetime = ServiceLifetime.Scoped) - where TDbContext : MasaDbContext + where TDbContextImplementation : MasaDbContext, IMasaDbContext => services - .AddDbContext(contextLifetime, optionsLifetime) - .AddCoreServices(optionsBuilder, optionsLifetime); + .AddDbContext(contextLifetime, optionsLifetime) + .AddCoreServices(optionsBuilder, optionsLifetime); private static IServiceCollection AddCoreServices( this IServiceCollection services, - Action? optionsBuilder, + Action? optionsBuilder, ServiceLifetime optionsLifetime) - where TDbContextImplementation : MasaDbContext + where TDbContextImplementation : MasaDbContext, IMasaDbContext { services.TryAddConfigure(); + + MasaDbContextOptionsBuilder masaBuilder = new MasaDbContextOptionsBuilder(services, typeof(TDbContextImplementation)); + optionsBuilder?.Invoke(masaBuilder); + return services.AddCoreServices((serviceProvider, efDbContextOptionsBuilder) => + { + if (masaBuilder.EnableSoftDelete) + efDbContextOptionsBuilder.UseSoftDelete(); + + masaBuilder.Builder.Invoke(serviceProvider, efDbContextOptionsBuilder.DbContextOptionsBuilder); + }, optionsLifetime); + } + + private static IServiceCollection AddCoreServices( + this IServiceCollection services, + Action? optionsBuilder, + ServiceLifetime optionsLifetime) + where TDbContextImplementation : MasaDbContext, IMasaDbContext + { services.TryAddScoped(); - services.TryAddScoped(typeof(DataFilter<>)); - services.TryAddScoped(); - services.TryAddEnumerable(new ServiceDescriptor(typeof(ISaveChangesFilter), typeof(SoftDeleteSaveChangesFilter), - ServiceLifetime.Scoped)); + services.TryAddSingleton(); services.TryAdd( new ServiceDescriptor( @@ -44,7 +46,7 @@ private static IServiceCollection AddCoreServices( serviceProvider => CreateMasaDbContextOptions(serviceProvider, optionsBuilder), optionsLifetime)); - services.Add( + services.TryAdd( new ServiceDescriptor( typeof(MasaDbContextOptions), serviceProvider => serviceProvider.GetRequiredService>(), @@ -52,43 +54,62 @@ private static IServiceCollection AddCoreServices( return services; } - private static MasaDbContextOptions CreateMasaDbContextOptions( + private static MasaDbContextOptions CreateMasaDbContextOptions( IServiceProvider serviceProvider, - Action? optionsBuilder) - where TDbContext : MasaDbContext + Action? optionsBuilder) + where TDbContextImplementation : MasaDbContext, IMasaDbContext { - var masaDbContextOptionsBuilder = new MasaDbContextOptionsBuilder(serviceProvider); - optionsBuilder?.Invoke(serviceProvider, masaDbContextOptionsBuilder); + var efDbContextOptionsBuilder = new EFDbContextOptionsBuilder(serviceProvider); + optionsBuilder?.Invoke(serviceProvider, efDbContextOptionsBuilder); - return CreateMasaDbContextOptions( + return CreateMasaDbContextOptions( serviceProvider, - masaDbContextOptionsBuilder.DbContextOptionsBuilder.Options, - masaDbContextOptionsBuilder.EnableSoftDelete); + efDbContextOptionsBuilder.DbContextOptionsBuilder.Options, + efDbContextOptionsBuilder.EnableSoftDelete); } - private static MasaDbContextOptions CreateMasaDbContextOptions(IServiceProvider serviceProvider, - DbContextOptions options, bool enableSoftDelete) where TDbContext : MasaDbContext => new(serviceProvider, options, enableSoftDelete); + private static MasaDbContextOptions CreateMasaDbContextOptions( + IServiceProvider serviceProvider, + DbContextOptions options, bool enableSoftDelete) + where TDbContextImplementation : MasaDbContext, IMasaDbContext + => new(serviceProvider, options, enableSoftDelete); private static IServiceCollection TryAddConfigure( this IServiceCollection services) where TOptions : class - => services.TryAddConfigure(Const.DEFAULT_SECTION); + => services.TryAddConfigure(ConnectionStrings.DEFAULT_SECTION); + /// + /// Only consider using MasaConfiguration and database configuration using local configuration + /// When using MasaConfiguration and the database configuration is stored in ConfigurationAPI, you need to specify the mapping relationship in Configuration by yourself + /// + /// + /// + /// + /// private static IServiceCollection TryAddConfigure( this IServiceCollection services, string sectionName) where TOptions : class { - IConfiguration? configuration = services.BuildServiceProvider().GetService(); + services.AddOptions(); + var serviceProvider = services.BuildServiceProvider(); + IConfiguration? configuration = serviceProvider.GetService()?.GetConfiguration(SectionTypes.Local) ?? + serviceProvider.GetService(); if (configuration == null) return services; string name = Options.DefaultName; - services.AddOptions(); var configurationSection = configuration.GetSection(sectionName); + if (!configurationSection.Exists()) + return services; + services.TryAddSingleton>( - new ConfigurationChangeTokenSource(name, configurationSection)); - services.TryAddSingleton>(new NamedConfigureFromConfigurationOptions(name, configurationSection, _ => { })); + new ConfigurationChangeTokenSource(name, configuration)); + services.TryAddSingleton>(new NamedConfigureFromConfigurationOptions(name, + configuration, _ => + { + })); return services; } } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/_Imports.cs index 0e887ef58..9e59f746f 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/_Imports.cs @@ -1,13 +1,15 @@ -global using Microsoft.EntityFrameworkCore; -global using Microsoft.Extensions.Options; +global using Masa.BuildingBlocks.Configuration; +global using Masa.BuildingBlocks.Data; global using Masa.BuildingBlocks.Data.Contracts.DataFiltering; -global using Microsoft.EntityFrameworkCore.Infrastructure; -global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.EntityFrameworkCore.ChangeTracking; +global using Masa.BuildingBlocks.Data.Options; global using Masa.Contrib.Data.EntityFrameworkCore.Filters; -global using System.Linq.Expressions; -global using System.Reflection; +global using Microsoft.EntityFrameworkCore; +global using Microsoft.EntityFrameworkCore.ChangeTracking; +global using Microsoft.EntityFrameworkCore.Infrastructure; global using Microsoft.EntityFrameworkCore.Metadata; -global using Masa.Contrib.Data.EntityFrameworkCore.Internal; global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.DependencyInjection.Extensions; +global using Microsoft.Extensions.Options; +global using System.Linq.Expressions; +global using System.Reflection; diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/DefaultConnectionStringProvider.cs b/src/Data/Masa.Contrib.Data.UoW.EF/DefaultConnectionStringProvider.cs index 9e51daaec..7d45dc43b 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/DefaultConnectionStringProvider.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/DefaultConnectionStringProvider.cs @@ -6,12 +6,12 @@ namespace Masa.Contrib.Data.UoW.EF; public class DefaultConnectionStringProvider : IConnectionStringProvider { private readonly IUnitOfWorkAccessor _unitOfWorkAccessor; - private readonly IOptionsSnapshot _options; + private readonly IOptionsMonitor _options; private readonly ILogger? _logger; public DefaultConnectionStringProvider( IUnitOfWorkAccessor unitOfWorkAccessor, - IOptionsSnapshot options, + IOptionsMonitor options, ILogger? logger = null) { _unitOfWorkAccessor = unitOfWorkAccessor; @@ -19,18 +19,19 @@ public DefaultConnectionStringProvider( _logger = logger; } - public Task GetConnectionStringAsync() => Task.FromResult(GetConnectionString()); + public Task GetConnectionStringAsync(string name = ConnectionStrings.DEFAULT_CONNECTION_STRING_NAME) => Task.FromResult(GetConnectionString(name)); - public string GetConnectionString() + public string GetConnectionString(string name = ConnectionStrings.DEFAULT_CONNECTION_STRING_NAME) { if (_unitOfWorkAccessor.CurrentDbContextOptions != null) return _unitOfWorkAccessor.CurrentDbContextOptions.ConnectionString; - var connectionString = _options.Value.DefaultConnection; + var connectionStrings = _options.CurrentValue.ConnectionStrings; + var connectionString = string.IsNullOrEmpty(name) ? connectionStrings.DefaultConnection : connectionStrings.GetConnectionString(name); if (string.IsNullOrEmpty(connectionString)) _logger?.LogError("Failed to get database connection string, please check whether the configuration of IOptionsSnapshot is abnormal"); - _unitOfWorkAccessor.CurrentDbContextOptions = new MasaDbContextConfigurationOptions(connectionString); + _unitOfWorkAccessor.CurrentDbContextOptions = new DbContextOptions(connectionString); return connectionString; } } diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/DispatcherOptionsExtensions.cs b/src/Data/Masa.Contrib.Data.UoW.EF/DispatcherOptionsExtensions.cs index d012b11d9..c04f6b1ed 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/DispatcherOptionsExtensions.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/DispatcherOptionsExtensions.cs @@ -10,9 +10,10 @@ public static IEventBusBuilder UseUoW( Action? optionsBuilder = null, bool disableRollbackOnFailure = false, bool useTransaction = true) - where TDbContext : MasaDbContext + where TDbContext : MasaDbContext, IMasaDbContext { - eventBusBuilder.Services.UseUoW(nameof(eventBusBuilder.Services), optionsBuilder, disableRollbackOnFailure, useTransaction); + eventBusBuilder.Services.UseUoW(nameof(eventBusBuilder.Services), optionsBuilder, disableRollbackOnFailure, + useTransaction); return eventBusBuilder; } @@ -21,7 +22,7 @@ public static IDispatcherOptions UseUoW( Action? optionsBuilder = null, bool disableRollbackOnFailure = false, bool useTransaction = true) - where TDbContext : MasaDbContext + where TDbContext : MasaDbContext, IMasaDbContext { options.Services.UseUoW(nameof(options.Services), optionsBuilder, disableRollbackOnFailure, useTransaction); return options; @@ -33,7 +34,7 @@ private static IServiceCollection UseUoW( Action? optionsBuilder = null, bool disableRollbackOnFailure = false, bool useTransaction = true) - where TDbContext : MasaDbContext + where TDbContext : MasaDbContext, IMasaDbContext { if (services == null) throw new ArgumentNullException(paramName); @@ -45,7 +46,6 @@ private static IServiceCollection UseUoW( services.TryAddScoped(); services.TryAddSingleton>(); services.TryAddScoped(); - services.TryAddSingleton(); services.AddScoped(serviceProvider => new UnitOfWork(serviceProvider) { @@ -53,44 +53,12 @@ private static IServiceCollection UseUoW( UseTransaction = useTransaction }); if (services.All(service => service.ServiceType != typeof(MasaDbContextOptions))) - { - services.TryAddConfigure(Const.DEFAULT_SECTION); services.AddMasaDbContext(optionsBuilder); - } services.AddScoped(); return services; } - /// - /// Only consider using MasaConfiguration and database configuration using local configuration - /// When using MasaConfiguration and the database configuration is stored in ConfigurationAPI, you need to specify the mapping relationship in Configuration by yourself - /// - /// - /// - /// - /// - private static IServiceCollection TryAddConfigure( - this IServiceCollection services, - string sectionName) - where TOptions : class - { - IMasaConfiguration? masaConfiguration = services.BuildServiceProvider().GetService(); - if (masaConfiguration == null) - return services; - - string name = Options.DefaultName; - services.AddOptions(); - var configurationSection = masaConfiguration.GetConfiguration(SectionTypes.Local).GetSection(sectionName); - if (!configurationSection.Exists()) - return services; - - services.TryAddSingleton>( - new ConfigurationChangeTokenSource(name, configurationSection)); - services.TryAddSingleton>(new NamedConfigureFromConfigurationOptions(name, configurationSection, _ => { })); - return services; - } - private class UoWProvider { } diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/Masa.Contrib.Data.UoW.EF.csproj b/src/Data/Masa.Contrib.Data.UoW.EF/Masa.Contrib.Data.UoW.EF.csproj index 2da76e10f..350ff23e2 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/Masa.Contrib.Data.UoW.EF.csproj +++ b/src/Data/Masa.Contrib.Data.UoW.EF/Masa.Contrib.Data.UoW.EF.csproj @@ -7,15 +7,15 @@ - - + + diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWork.cs b/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWork.cs index 928a72a63..9a65a05d4 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWork.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWork.cs @@ -3,7 +3,7 @@ namespace Masa.Contrib.Data.UoW.EF; -public class UnitOfWork : IUnitOfWork where TDbContext : MasaDbContext +public class UnitOfWork : IUnitOfWork where TDbContext : MasaDbContext, IMasaDbContext { public IServiceProvider ServiceProvider { get; } diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkAccessor.cs b/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkAccessor.cs index eb0814c88..e69401698 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkAccessor.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkAccessor.cs @@ -5,5 +5,5 @@ namespace Masa.Contrib.Data.UoW.EF; public class UnitOfWorkAccessor : IUnitOfWorkAccessor { - public MasaDbContextConfigurationOptions? CurrentDbContextOptions { get; set; } + public DbContextOptions? CurrentDbContextOptions { get; set; } } diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkManager.cs b/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkManager.cs index fdec51399..1f0f3294d 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkManager.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkManager.cs @@ -3,7 +3,7 @@ namespace Masa.Contrib.Data.UoW.EF; -public class UnitOfWorkManager : IUnitOfWorkManager where TDbContext : MasaDbContext +public class UnitOfWorkManager : IUnitOfWorkManager where TDbContext : MasaDbContext, IMasaDbContext { private readonly IServiceProvider _serviceProvider; @@ -24,7 +24,7 @@ public IUnitOfWork CreateDbContext(bool lazyLoading = true) return scope.ServiceProvider.GetRequiredService(); } - public IUnitOfWork CreateDbContext(MasaDbContextConfigurationOptions options) + public IUnitOfWork CreateDbContext(DbContextOptions options) { ArgumentNullException.ThrowIfNull(options, nameof(options)); if (string.IsNullOrEmpty(options.ConnectionString)) diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs b/src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs index 42ce36d59..a25dd87b0 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs @@ -3,9 +3,7 @@ global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Data.UoW; -global using Masa.BuildingBlocks.Data.UoW.Options; global using Masa.BuildingBlocks.Dispatcher.Events; -global using Masa.Utils.Data.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.Storage; global using Microsoft.Extensions.Configuration; @@ -16,5 +14,7 @@ global using System.Data.Common; global using System.Text.Json.Serialization; global using EntityState = Masa.BuildingBlocks.Data.UoW.EntityState; -global using DbContextOptions = Masa.BuildingBlocks.Data.UoW.Options.MasaDbContextConfigurationOptions; +global using DbContextOptions = Masa.BuildingBlocks.Data.Options.MasaDbContextConfigurationOptions; global using Masa.Contrib.Data.UoW.EF.Internal; +global using Masa.BuildingBlocks.Data; +global using Masa.Contrib.Data.EntityFrameworkCore; diff --git a/src/Ddd/Masa.Contrib.Ddd.Domain.Repository.EF/Repository.cs b/src/Ddd/Masa.Contrib.Ddd.Domain.Repository.EF/Repository.cs index ac366a67d..a85c819ec 100644 --- a/src/Ddd/Masa.Contrib.Ddd.Domain.Repository.EF/Repository.cs +++ b/src/Ddd/Masa.Contrib.Ddd.Domain.Repository.EF/Repository.cs @@ -126,7 +126,7 @@ public override async Task> GetListAsync( /// public override Task> GetPaginatedListAsync(int skip, int take, string sortField, bool isDescending, CancellationToken cancellationToken = default) - => Context.Set().OrderBy(sortField, isDescending).Skip(skip).Take(take).ToListAsync(cancellationToken: cancellationToken); + => Context.Set().OrderBy(sortField, isDescending).Skip(skip).Take(take).ToListAsync(cancellationToken); /// /// Get a paginated list after sorting according to skip and take @@ -159,7 +159,7 @@ public override Task> GetPaginatedListAsync( /// public override Task> GetPaginatedListAsync(Expression> predicate, int skip, int take, string sortField, bool isDescending = true, CancellationToken cancellationToken = default) - => Context.Set().Where(predicate).OrderBy(sortField, isDescending).Skip(skip).Take(take).ToListAsync(cancellationToken: cancellationToken); + => Context.Set().Where(predicate).OrderBy(sortField, isDescending).Skip(skip).Take(take).ToListAsync(cancellationToken); /// /// Get a paginated list after sorting by condition diff --git a/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr/_Imports.cs b/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr/_Imports.cs index 5d7e3f684..7efd8b51f 100644 --- a/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr/_Imports.cs +++ b/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr/_Imports.cs @@ -19,3 +19,4 @@ global using System.Collections.Concurrent; global using System.Reflection; global using System.Text.Json.Serialization; +global using Masa.BuildingBlocks.Data; diff --git a/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF/DispatcherOptionsExtensions.cs b/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF/DispatcherOptionsExtensions.cs index 02d3fee61..2031ad298 100644 --- a/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF/DispatcherOptionsExtensions.cs +++ b/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF/DispatcherOptionsExtensions.cs @@ -13,7 +13,7 @@ public static class DispatcherOptionsExtensions /// /// public static IDispatcherOptions UseEventLog( - this IDispatcherOptions options) where TDbContext : MasaDbContext + this IDispatcherOptions options) where TDbContext : MasaDbContext, IMasaDbContext { if (options.Services == null) throw new ArgumentNullException(nameof(options.Services)); diff --git a/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.csproj b/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.csproj index a92295422..e9c553948 100644 --- a/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.csproj +++ b/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.csproj @@ -7,7 +7,6 @@ - @@ -15,6 +14,7 @@ + diff --git a/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF/_Imports.cs b/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF/_Imports.cs index b1cf34ded..4abb3581e 100644 --- a/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF/_Imports.cs +++ b/src/Dispatcher/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF/_Imports.cs @@ -1,12 +1,13 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Masa.BuildingBlocks.Data; global using Masa.BuildingBlocks.Dispatcher.Events; global using Masa.BuildingBlocks.Dispatcher.IntegrationEvents; global using Masa.BuildingBlocks.Dispatcher.IntegrationEvents.Logs; +global using Masa.Contrib.Data.EntityFrameworkCore; global using Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Internal; global using Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Internal.Options; -global using Masa.Utils.Data.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.Metadata; global using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/src/Isolation/Masa.Contrib.Isolation.UoW.EF/DefaultConnectionStringProvider.cs b/src/Isolation/Masa.Contrib.Isolation.UoW.EF/DefaultConnectionStringProvider.cs deleted file mode 100644 index 22d40734f..000000000 --- a/src/Isolation/Masa.Contrib.Isolation.UoW.EF/DefaultConnectionStringProvider.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Isolation.UoW.EF; - -public class DefaultConnectionStringProvider : IConnectionStringProvider -{ - private readonly IIsolationDbConnectionStringProvider _isolationConnectionStringProvider; - - public DefaultConnectionStringProvider(IIsolationDbConnectionStringProvider isolationConnectionStringProvider) - => _isolationConnectionStringProvider = isolationConnectionStringProvider; - - public Task GetConnectionStringAsync() => _isolationConnectionStringProvider.GetConnectionStringAsync(); - - public string GetConnectionString() => _isolationConnectionStringProvider.GetConnectionString(); -} diff --git a/src/Isolation/Masa.Contrib.Isolation.UoW.EF/DispatcherOptionsExtensions.cs b/src/Isolation/Masa.Contrib.Isolation.UoW.EF/DispatcherOptionsExtensions.cs index 7e3868087..c7075b2c2 100644 --- a/src/Isolation/Masa.Contrib.Isolation.UoW.EF/DispatcherOptionsExtensions.cs +++ b/src/Isolation/Masa.Contrib.Isolation.UoW.EF/DispatcherOptionsExtensions.cs @@ -11,7 +11,7 @@ public static IEventBusBuilder UseIsolationUoW( Action? optionsBuilder, bool disableRollbackOnFailure = false, bool useTransaction = true) - where TDbContext : MasaDbContext + where TDbContext : MasaDbContext, IMasaDbContext => eventBusBuilder.UseIsolationUoW(isolationBuilder, optionsBuilder, disableRollbackOnFailure, useTransaction); public static IEventBusBuilder UseIsolationUoW( @@ -20,7 +20,7 @@ public static IEventBusBuilder UseIsolationUoW( Action? optionsBuilder, bool disableRollbackOnFailure = false, bool useTransaction = true) - where TDbContext : MasaDbContext + where TDbContext : MasaDbContext, IMasaDbContext where TKey : IComparable { eventBusBuilder.Services.UseIsolationUoW(); @@ -34,7 +34,7 @@ public static IDispatcherOptions UseIsolationUoW( Action? optionsBuilder, bool disableRollbackOnFailure = false, bool useTransaction = true) - where TDbContext : MasaDbContext + where TDbContext : MasaDbContext, IMasaDbContext => options.UseIsolationUoW(isolationBuilder, optionsBuilder, disableRollbackOnFailure, useTransaction); public static IDispatcherOptions UseIsolationUoW( @@ -43,7 +43,7 @@ public static IDispatcherOptions UseIsolationUoW( Action? optionsBuilder, bool disableRollbackOnFailure = false, bool useTransaction = true) - where TDbContext : MasaDbContext + where TDbContext : MasaDbContext, IMasaDbContext where TKey : IComparable { options.Services.UseIsolationUoW(); @@ -52,19 +52,5 @@ public static IDispatcherOptions UseIsolationUoW( } private static void UseIsolationUoW(this IServiceCollection services) where TKey : IComparable - => services.UseIsolationUoW() - .TryAddEnumerable(new ServiceDescriptor(typeof(ISaveChangesFilter), typeof(IsolationSaveChangesFilter), ServiceLifetime.Scoped)); - - private static IServiceCollection UseIsolationUoW(this IServiceCollection services) - { - if (services.Any(service => service.ServiceType == typeof(IConnectionStringProvider))) - services.Replace(new ServiceDescriptor(typeof(IConnectionStringProvider), typeof(DefaultConnectionStringProvider), ServiceLifetime.Scoped)); - else - services.TryAddScoped(); - return services; - } - - private class IsolationUoWProvider - { - } + => services.TryAddEnumerable(new ServiceDescriptor(typeof(ISaveChangesFilter), typeof(IsolationSaveChangesFilter), ServiceLifetime.Scoped)); } diff --git a/src/Isolation/Masa.Contrib.Isolation.UoW.EF/IsolationDbContext.cs b/src/Isolation/Masa.Contrib.Isolation.UoW.EF/IsolationDbContext.cs index dadf28946..3a41a6fc7 100644 --- a/src/Isolation/Masa.Contrib.Isolation.UoW.EF/IsolationDbContext.cs +++ b/src/Isolation/Masa.Contrib.Isolation.UoW.EF/IsolationDbContext.cs @@ -3,6 +3,24 @@ namespace Masa.Contrib.Isolation.UoW.EF; +/// +/// DbContext providing isolation +/// +/// tenant id type +/// +public abstract class IsolationDbContext : IsolationDbContext + where TKey : IComparable + where TDbContext : DbContext, IMasaDbContext +{ + protected IsolationDbContext(MasaDbContextOptions options) : base(options) + { + } +} + +/// +/// DbContext providing isolation +/// +/// tenant id type public abstract class IsolationDbContext : IsolationDbContext { protected IsolationDbContext(MasaDbContextOptions options) : base(options) diff --git a/src/Isolation/Masa.Contrib.Isolation.UoW.EF/_Imports.cs b/src/Isolation/Masa.Contrib.Isolation.UoW.EF/_Imports.cs index 8236526f1..0c716833b 100644 --- a/src/Isolation/Masa.Contrib.Isolation.UoW.EF/_Imports.cs +++ b/src/Isolation/Masa.Contrib.Isolation.UoW.EF/_Imports.cs @@ -1,14 +1,15 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Masa.BuildingBlocks.Data; global using Masa.BuildingBlocks.Dispatcher.Events; global using Masa.BuildingBlocks.Isolation; global using Masa.BuildingBlocks.Isolation.Environment; global using Masa.BuildingBlocks.Isolation.MultiTenant; +global using Masa.Contrib.Data.EntityFrameworkCore; +global using Masa.Contrib.Data.EntityFrameworkCore.Filters; global using Masa.Contrib.Data.UoW.EF; global using Masa.Contrib.Isolation.UoW.EF.Internal; -global using Masa.Utils.Data.EntityFrameworkCore; -global using Masa.Utils.Data.EntityFrameworkCore.Filters; global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.ChangeTracking; global using Microsoft.Extensions.DependencyInjection; diff --git a/src/Isolation/Masa.Contrib.Isolation/DefaultIsolationConnectionStringProvider.cs b/src/Isolation/Masa.Contrib.Isolation/DefaultIsolationConnectionStringProvider.cs index 35e106cb2..c7d630b9c 100644 --- a/src/Isolation/Masa.Contrib.Isolation/DefaultIsolationConnectionStringProvider.cs +++ b/src/Isolation/Masa.Contrib.Isolation/DefaultIsolationConnectionStringProvider.cs @@ -3,7 +3,7 @@ namespace Masa.Contrib.Isolation; -public class DefaultDbIsolationConnectionStringProvider : IIsolationDbConnectionStringProvider +public class DefaultDbIsolationConnectionStringProvider : IConnectionStringProvider { private readonly IUnitOfWorkAccessor _unitOfWorkAccessor; private readonly IOptionsSnapshot _options; @@ -25,46 +25,54 @@ public DefaultDbIsolationConnectionStringProvider( _logger = logger; } - public Task GetConnectionStringAsync() => Task.FromResult(GetConnectionString()); + public Task GetConnectionStringAsync(string name = ConnectionStrings.DEFAULT_CONNECTION_STRING_NAME) => Task.FromResult(GetConnectionString(name)); - public string GetConnectionString() + public string GetConnectionString(string name = ConnectionStrings.DEFAULT_CONNECTION_STRING_NAME) { if (_unitOfWorkAccessor.CurrentDbContextOptions != null) - return _unitOfWorkAccessor.CurrentDbContextOptions.ConnectionString; + return _unitOfWorkAccessor.CurrentDbContextOptions.ConnectionString; //todo: UnitOfWork does not currently support multi-context versions - Expression> condition = option => true; + Expression> condition = option + => name != ConnectionStrings.DEFAULT_CONNECTION_STRING_NAME ? option.Name == name : option.Name == name || option.Name == string.Empty; if (_tenantContext != null) { if (_tenantContext.CurrentTenant == null) - _logger?.LogDebug($"Tenant resolution failed, the currently used ConnectionString is [{nameof(_options.Value.DefaultConnection)}]"); + _logger?.LogDebug( + $"Tenant resolution failed, the currently used ConnectionString is [{nameof(_options.Value.ConnectionStrings.DefaultConnection)}]"); - condition = condition.And(option => option.TenantId == "*" || (_tenantContext.CurrentTenant != null && _tenantContext.CurrentTenant.Id.Equals(option.TenantId, StringComparison.CurrentCultureIgnoreCase))); + condition = condition.And(option => option.TenantId == "*" || (_tenantContext.CurrentTenant != null && + _tenantContext.CurrentTenant.Id.Equals(option.TenantId, StringComparison.CurrentCultureIgnoreCase))); } if (_environmentContext != null) { if (string.IsNullOrEmpty(_environmentContext.CurrentEnvironment)) { - _logger?.LogDebug($"Environment resolution failed, the currently used ConnectionString is [{nameof(_options.Value.DefaultConnection)}]"); + _logger?.LogDebug( + $"Environment resolution failed, the currently used ConnectionString is [{nameof(_options.Value.ConnectionStrings.DefaultConnection)}]"); } condition = condition.And(option - => option.Environment == "*" || option.Environment.Equals(_environmentContext.CurrentEnvironment, StringComparison.CurrentCultureIgnoreCase)); + => option.Environment == "*" || + option.Environment.Equals(_environmentContext.CurrentEnvironment, StringComparison.CurrentCultureIgnoreCase)); } string? connectionString; - var list = _options.Value.Isolations.Where(condition.Compile()).ToList(); + var list = _options.Value.IsolationConnectionStrings.Where(condition.Compile()).ToList(); if (list.Count >= 1) { connectionString = list.OrderByDescending(option => option.Score).Select(option => option.ConnectionString).FirstOrDefault()!; if (list.Count > 1) - _logger?.LogInformation("{Message}, Matches multiple available database link strings, the currently used ConnectionString is [{ConnectionString}]", GetMessage(), connectionString); + _logger?.LogInformation( + "{Message}, Matches multiple available database link strings, the currently used ConnectionString is [{ConnectionString}]", + GetMessage(), connectionString); } else { - connectionString = _options.Value.DefaultConnection; - _logger?.LogDebug("{Message}, the currently used ConnectionString is [{ConnectionString}]", GetMessage(), nameof(_options.Value.DefaultConnection)); + connectionString = _options.Value.ConnectionStrings.DefaultConnection; + _logger?.LogDebug("{Message}, the currently used ConnectionString is [{ConnectionString}]", GetMessage(), + nameof(_options.Value.ConnectionStrings.DefaultConnection)); } return SetConnectionString(connectionString); } @@ -72,7 +80,7 @@ public string GetConnectionString() private string SetConnectionString(string? connectionString = null) { _unitOfWorkAccessor.CurrentDbContextOptions = - new MasaDbContextConfigurationOptions(connectionString ?? _options.Value.DefaultConnection); + new MasaDbContextConfigurationOptions(connectionString ?? _options.Value.ConnectionStrings.DefaultConnection); return _unitOfWorkAccessor.CurrentDbContextOptions.ConnectionString; } diff --git a/src/Isolation/Masa.Contrib.Isolation/DispatcherOptionsExtensions.cs b/src/Isolation/Masa.Contrib.Isolation/DispatcherOptionsExtensions.cs index 461430e88..c3ef19ea9 100644 --- a/src/Isolation/Masa.Contrib.Isolation/DispatcherOptionsExtensions.cs +++ b/src/Isolation/Masa.Contrib.Isolation/DispatcherOptionsExtensions.cs @@ -42,38 +42,42 @@ private static void AddIsolation(this IServiceCollection services, Action service.ServiceType == typeof(ITenantContext) || service.ServiceType == typeof(IEnvironmentContext)) < - 1) + if (services.Count(service => + service.ServiceType == typeof(ITenantContext) || + service.ServiceType == typeof(IEnvironmentContext)) < 1) throw new NotSupportedException("Tenant isolation and environment isolation use at least one"); services.AddHttpContextAccessor(); services - .TryAddConfigure(Const.DEFAULT_SECTION) + .TryAddConfigure() .AddTransient(typeof(IMiddleware<>), typeof(IsolationMiddleware<>)) .TryAddSingleton(); - services.TryAddScoped(typeof(IIsolationDbConnectionStringProvider), typeof(DefaultDbIsolationConnectionStringProvider)); + + if (services.Any(service => service.ServiceType == typeof(IConnectionStringProvider))) + services.Replace(new ServiceDescriptor(typeof(IConnectionStringProvider), typeof(DefaultDbIsolationConnectionStringProvider), ServiceLifetime.Scoped)); + else + services.TryAddScoped(); } private static IServiceCollection TryAddConfigure( - this IServiceCollection services, - string sectionName) + this IServiceCollection services) where TOptions : class { + services.AddOptions(); var serviceProvider = services.BuildServiceProvider(); IConfiguration? configuration = serviceProvider.GetService()?.GetConfiguration(SectionTypes.Local) ?? serviceProvider.GetService(); + if (configuration == null) return services; string name = Options.DefaultName; - services.AddOptions(); - var configurationSection = configuration.GetSection(sectionName); services.TryAddSingleton>( - new ConfigurationChangeTokenSource(name, configurationSection)); + new ConfigurationChangeTokenSource(name, configuration)); services.TryAddSingleton>(new NamedConfigureFromConfigurationOptions( name, - configurationSection, _ => + configuration, _ => { })); return services; diff --git a/src/Isolation/Masa.Contrib.Isolation/Internal/Const.cs b/src/Isolation/Masa.Contrib.Isolation/Internal/Const.cs deleted file mode 100644 index 2c62b3694..000000000 --- a/src/Isolation/Masa.Contrib.Isolation/Internal/Const.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. - -namespace Masa.Contrib.Isolation.Internal; - -internal class Const -{ - public const string DEFAULT_SECTION = "ConnectionStrings"; -} diff --git a/src/Isolation/Masa.Contrib.Isolation/IsolationDbContextProvider.cs b/src/Isolation/Masa.Contrib.Isolation/IsolationDbContextProvider.cs index 4cc2de95e..6f13962b9 100644 --- a/src/Isolation/Masa.Contrib.Isolation/IsolationDbContextProvider.cs +++ b/src/Isolation/Masa.Contrib.Isolation/IsolationDbContextProvider.cs @@ -11,12 +11,12 @@ public class IsolationDbContextProvider : BaseDbConnectionStringProvider protected override List GetDbContextOptionsList() { - var connectionStrings = _options.CurrentValue.Isolations + var connectionStrings = _options.CurrentValue.IsolationConnectionStrings .Select(connectionString => connectionString.ConnectionString) .Distinct() .ToList(); - if (!connectionStrings.Contains(_options.CurrentValue.DefaultConnection)) - connectionStrings.Add(_options.CurrentValue.DefaultConnection); + if (!connectionStrings.Contains(_options.CurrentValue.ConnectionStrings.DefaultConnection)) + connectionStrings.Add(_options.CurrentValue.ConnectionStrings.DefaultConnection); return connectionStrings.Select(connectionString => new MasaDbContextConfigurationOptions(connectionString)).ToList(); } diff --git a/src/Isolation/Masa.Contrib.Isolation/Masa.Contrib.Isolation.csproj b/src/Isolation/Masa.Contrib.Isolation/Masa.Contrib.Isolation.csproj index 7b2d2648b..e92dd5fb0 100644 --- a/src/Isolation/Masa.Contrib.Isolation/Masa.Contrib.Isolation.csproj +++ b/src/Isolation/Masa.Contrib.Isolation/Masa.Contrib.Isolation.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Isolation/Masa.Contrib.Isolation/_Imports.cs b/src/Isolation/Masa.Contrib.Isolation/_Imports.cs index 7040fc4c0..30a02286c 100644 --- a/src/Isolation/Masa.Contrib.Isolation/_Imports.cs +++ b/src/Isolation/Masa.Contrib.Isolation/_Imports.cs @@ -3,14 +3,12 @@ global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Data.UoW; -global using Masa.BuildingBlocks.Data.UoW.Options; global using Masa.BuildingBlocks.Dispatcher.Events; global using Masa.BuildingBlocks.Isolation; global using Masa.BuildingBlocks.Isolation.Environment; global using Masa.BuildingBlocks.Isolation.Middleware; global using Masa.BuildingBlocks.Isolation.MultiTenant; global using Masa.BuildingBlocks.Isolation.Options; -global using Masa.Contrib.Isolation.Internal; global using Masa.Contrib.Isolation.Middleware; global using Microsoft.AspNetCore.Builder; global using Microsoft.AspNetCore.Http; @@ -20,3 +18,5 @@ global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; global using System.Linq.Expressions; +global using Masa.BuildingBlocks.Data; +global using Masa.BuildingBlocks.Data.Options; diff --git a/test/Masa.Contrib.Data.Contracts.EF.Tests/Masa.Contrib.Data.Contracts.EF.Tests.csproj b/test/Masa.Contrib.Data.Contracts.EF.Tests/Masa.Contrib.Data.Contracts.EF.Tests.csproj index b8ab51962..9c9838ff4 100644 --- a/test/Masa.Contrib.Data.Contracts.EF.Tests/Masa.Contrib.Data.Contracts.EF.Tests.csproj +++ b/test/Masa.Contrib.Data.Contracts.EF.Tests/Masa.Contrib.Data.Contracts.EF.Tests.csproj @@ -25,7 +25,6 @@ - diff --git a/test/Masa.Contrib.Data.UoW.EF.Tests/Masa.Contrib.Data.UoW.EF.Tests.csproj b/test/Masa.Contrib.Data.UoW.EF.Tests/Masa.Contrib.Data.UoW.EF.Tests.csproj index d5628d898..ec650a403 100644 --- a/test/Masa.Contrib.Data.UoW.EF.Tests/Masa.Contrib.Data.UoW.EF.Tests.csproj +++ b/test/Masa.Contrib.Data.UoW.EF.Tests/Masa.Contrib.Data.UoW.EF.Tests.csproj @@ -12,7 +12,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -33,6 +32,7 @@ + diff --git a/test/Masa.Contrib.Data.UoW.EF.Tests/TestUnitOfWork.cs b/test/Masa.Contrib.Data.UoW.EF.Tests/TestUnitOfWork.cs index 6db3079ac..4026488a8 100644 --- a/test/Masa.Contrib.Data.UoW.EF.Tests/TestUnitOfWork.cs +++ b/test/Masa.Contrib.Data.UoW.EF.Tests/TestUnitOfWork.cs @@ -160,7 +160,7 @@ public void TestDataConnectionString() var serviceProvider = _options.Object.Services.BuildServiceProvider(); var dataConnectionStringProvider = serviceProvider.GetRequiredService(); Assert.IsTrue(dataConnectionStringProvider.DbContextOptionsList.Count == 1 && - dataConnectionStringProvider.DbContextOptionsList.Any(option => option.ConnectionString == null)); + dataConnectionStringProvider.DbContextOptionsList.Any(option => option.ConnectionString == _connectionString)); } [TestMethod] @@ -176,13 +176,13 @@ public void TestUnitOfWorkManager() var newUnitOfWork = unitOfWorkManager.CreateDbContext( - new Masa.BuildingBlocks.Data.UoW.Options.MasaDbContextConfigurationOptions(_connectionString)); + new MasaDbContextConfigurationOptions(_connectionString)); Assert.IsFalse(newUnitOfWork.Equals(unitOfWork)); var newDbContext = newUnitOfWork.ServiceProvider.GetRequiredService(); Assert.IsFalse(dbContext.Equals(newDbContext)); Assert.ThrowsException(() - => unitOfWorkManager.CreateDbContext(new BuildingBlocks.Data.UoW.Options.MasaDbContextConfigurationOptions(""))); + => unitOfWorkManager.CreateDbContext(new MasaDbContextConfigurationOptions(""))); } [TestMethod] @@ -214,7 +214,7 @@ public async Task TestUnitOfWorkAccessorAsync() configurationRoot["ConnectionStrings:DefaultConnection"].ToString()); var unitOfWorkNew2 = - unitOfWorkManager.CreateDbContext(new BuildingBlocks.Data.UoW.Options.MasaDbContextConfigurationOptions("test")); + unitOfWorkManager.CreateDbContext(new MasaDbContextConfigurationOptions("test")); var unitOfWorkAccessorNew2 = unitOfWorkNew2.ServiceProvider.GetService(); Assert.IsTrue(unitOfWorkAccessorNew2!.CurrentDbContextOptions != null && unitOfWorkAccessorNew2.CurrentDbContextOptions.ConnectionString == "test"); diff --git a/test/Masa.Contrib.Data.UoW.EF.Tests/_Imports.cs b/test/Masa.Contrib.Data.UoW.EF.Tests/_Imports.cs index 980fd9e19..d068d67aa 100644 --- a/test/Masa.Contrib.Data.UoW.EF.Tests/_Imports.cs +++ b/test/Masa.Contrib.Data.UoW.EF.Tests/_Imports.cs @@ -2,11 +2,12 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. global using Masa.BuildingBlocks.Configuration; +global using Masa.BuildingBlocks.Data; global using Masa.BuildingBlocks.Data.UoW; global using Masa.BuildingBlocks.Dispatcher.Events; global using Masa.Contrib.Configuration; -global using Masa.Utils.Data.EntityFrameworkCore; -global using Masa.Utils.Data.EntityFrameworkCore.Sqlite; +global using Masa.Contrib.Data.EntityFrameworkCore; +global using Masa.Contrib.Data.EntityFrameworkCore.Sqlite; global using Microsoft.AspNetCore.Builder; global using Microsoft.Data.Sqlite; global using Microsoft.EntityFrameworkCore; @@ -17,3 +18,4 @@ global using Moq; global using System; global using System.Threading.Tasks; +global using Masa.BuildingBlocks.Data.Options; diff --git a/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/Masa.Contrib.Ddd.Domain.Repository.EF.Tests.csproj b/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/Masa.Contrib.Ddd.Domain.Repository.EF.Tests.csproj index bf0ff6e29..df6b25bdb 100644 --- a/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/Masa.Contrib.Ddd.Domain.Repository.EF.Tests.csproj +++ b/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/Masa.Contrib.Ddd.Domain.Repository.EF.Tests.csproj @@ -12,7 +12,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - @@ -25,6 +24,7 @@ + diff --git a/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/RepositoryTest.cs b/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/RepositoryTest.cs index 855a1b3ab..8194742f8 100644 --- a/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/RepositoryTest.cs +++ b/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/RepositoryTest.cs @@ -248,8 +248,9 @@ public async Task TestUpdateAsync() await InitializeAsync(services => services.AddMasaDbContext(options => { - options.DbContextOptionsBuilder.UseSqlite(Connection) - .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); + options.Builder = (_, dbContextOptionsBuilder) + => dbContextOptionsBuilder.UseSqlite(Connection) + .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); })); _dispatcherOptions.Object.UseRepository(); diff --git a/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/_Imports.cs b/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/_Imports.cs index e21570961..1c78b0762 100644 --- a/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/_Imports.cs +++ b/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/_Imports.cs @@ -7,13 +7,13 @@ global using Masa.BuildingBlocks.Ddd.Domain.Repositories; global using Masa.BuildingBlocks.Ddd.Domain.Values; global using Masa.BuildingBlocks.Dispatcher.Events; +global using Masa.Contrib.Data.EntityFrameworkCore; +global using Masa.Contrib.Data.EntityFrameworkCore.Sqlite; global using Masa.Contrib.Data.UoW.EF; global using Masa.Contrib.Ddd.Domain.Repository.EF.CustomRepository.Tests.Repositories; global using Masa.Contrib.Ddd.Domain.Repository.EF.Tests.Domain.Entities; global using Masa.Contrib.Ddd.Domain.Repository.EF.Tests.Domain.Repositories; global using Masa.Contrib.Ddd.Domain.Repository.EF.Tests.Infrastructure; -global using Masa.Utils.Data.EntityFrameworkCore; -global using Masa.Utils.Data.EntityFrameworkCore.Sqlite; global using Microsoft.Data.Sqlite; global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.Storage; diff --git a/test/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.Tests/ProcessorTest.cs b/test/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.Tests/ProcessorTest.cs index 08b013017..893dc776e 100644 --- a/test/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.Tests/ProcessorTest.cs +++ b/test/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.Tests/ProcessorTest.cs @@ -79,11 +79,11 @@ public async Task RetryByDataProcessorExecuteTestAsync() services.AddScoped(_ => uoW.Object); Mock unitOfWorkManager = new(); - unitOfWorkManager.Setup(uoWManager => uoWManager.CreateDbContext(It.IsAny())).Returns(uoW.Object).Verifiable(); + unitOfWorkManager.Setup(uoWManager => uoWManager.CreateDbContext(It.IsAny())).Returns(uoW.Object).Verifiable(); services.AddSingleton(_ => unitOfWorkManager.Object); Mock dataConnectionStringProvider = new(); - dataConnectionStringProvider.Setup(provider => provider.DbContextOptionsList).Returns(new List + dataConnectionStringProvider.Setup(provider => provider.DbContextOptionsList).Returns(new List { new(string.Empty) }).Verifiable(); @@ -157,11 +157,11 @@ public async Task RetryByDataProcessorExecute2TestAsync() services.AddScoped(_ => uoW.Object); Mock unitOfWorkManager = new(); - unitOfWorkManager.Setup(uoWManager => uoWManager.CreateDbContext(It.IsAny())).Returns(uoW.Object).Verifiable(); + unitOfWorkManager.Setup(uoWManager => uoWManager.CreateDbContext(It.IsAny())).Returns(uoW.Object).Verifiable(); services.AddSingleton(_ => unitOfWorkManager.Object); Mock dataConnectionStringProvider = new(); - dataConnectionStringProvider.Setup(provider => provider.DbContextOptionsList).Returns(new List + dataConnectionStringProvider.Setup(provider => provider.DbContextOptionsList).Returns(new List { new(string.Empty) }).Verifiable(); @@ -242,11 +242,11 @@ public async Task RetryByDataProcessorExecute2AndNotUseLoggerTestAsync() services.AddScoped(_ => uoW.Object); Mock unitOfWorkManager = new(); - unitOfWorkManager.Setup(uoWManager => uoWManager.CreateDbContext(It.IsAny())).Returns(uoW.Object).Verifiable(); + unitOfWorkManager.Setup(uoWManager => uoWManager.CreateDbContext(It.IsAny())).Returns(uoW.Object).Verifiable(); services.AddSingleton(_ => unitOfWorkManager.Object); Mock dataConnectionStringProvider = new(); - dataConnectionStringProvider.Setup(provider => provider.DbContextOptionsList).Returns(new List() + dataConnectionStringProvider.Setup(provider => provider.DbContextOptionsList).Returns(new List() { new(string.Empty) }).Verifiable(); @@ -283,11 +283,11 @@ public async Task DeletePublishedExpireEventProcessorExecuteTestAsync() uoW.Setup(uow => uow.ServiceProvider).Returns(_options.Value.Services.BuildServiceProvider()).Verifiable(); Mock unitOfWorkManager = new(); - unitOfWorkManager.Setup(uoWManager => uoWManager.CreateDbContext(It.IsAny())).Returns(uoW.Object).Verifiable(); + unitOfWorkManager.Setup(uoWManager => uoWManager.CreateDbContext(It.IsAny())).Returns(uoW.Object).Verifiable(); _options.Value.Services.AddSingleton(_ => unitOfWorkManager.Object); Mock dataConnectionStringProvider = new(); - dataConnectionStringProvider.Setup(provider => provider.DbContextOptionsList).Returns(new List() + dataConnectionStringProvider.Setup(provider => provider.DbContextOptionsList).Returns(new List() { new(string.Empty) }).Verifiable(); diff --git a/test/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.Tests/_Imports.cs b/test/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.Tests/_Imports.cs index 5e3534597..3f1363bbc 100644 --- a/test/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.Tests/_Imports.cs +++ b/test/Masa.Contrib.Dispatcher.IntegrationEvents.Dapr.Tests/_Imports.cs @@ -19,3 +19,5 @@ global using Moq; global using System.Data.Common; global using System.Reflection; +global using Masa.BuildingBlocks.Data; +global using Masa.BuildingBlocks.Data.Options; diff --git a/test/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests.csproj b/test/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests.csproj index a4259aa5d..a79a2b295 100644 --- a/test/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests.csproj +++ b/test/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests.csproj @@ -16,7 +16,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - @@ -25,6 +24,7 @@ + diff --git a/test/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests/_Imports.cs b/test/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests/_Imports.cs index cafaac975..b64233a57 100644 --- a/test/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests/_Imports.cs +++ b/test/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests/_Imports.cs @@ -5,11 +5,11 @@ global using Masa.BuildingBlocks.Dispatcher.Events; global using Masa.BuildingBlocks.Dispatcher.IntegrationEvents; global using Masa.BuildingBlocks.Dispatcher.IntegrationEvents.Logs; +global using Masa.Contrib.Data.EntityFrameworkCore; +global using Masa.Contrib.Data.EntityFrameworkCore.Sqlite; global using Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests.Domain.Entities; global using Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests.Events; global using Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests.Infrastructure; -global using Masa.Utils.Data.EntityFrameworkCore; -global using Masa.Utils.Data.EntityFrameworkCore.Sqlite; global using Microsoft.Data.Sqlite; global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.Storage; diff --git a/test/Masa.Contrib.Isolation.Tests/TestDbIsolationConnectionStringProvider.cs b/test/Masa.Contrib.Isolation.Tests/TestDbIsolationConnectionStringProvider.cs index e0047429b..67e394dd9 100644 --- a/test/Masa.Contrib.Isolation.Tests/TestDbIsolationConnectionStringProvider.cs +++ b/test/Masa.Contrib.Isolation.Tests/TestDbIsolationConnectionStringProvider.cs @@ -22,32 +22,38 @@ public async Task TestGetConnectionStringAsync() var unitOfWorkAccessor = _services.BuildServiceProvider().GetService()!; unitOfWorkAccessor.CurrentDbContextOptions = new MasaDbContextConfigurationOptions(defaultConnectionString); var provider = new DefaultDbIsolationConnectionStringProvider(unitOfWorkAccessor, null!); + Assert.IsTrue(await provider.GetConnectionStringAsync() == defaultConnectionString); } [TestMethod] public async Task TestGetConnectionString2Async() { - string defaultConnectionString = "data source=test1;"; - - _services.Configure(option => option.DefaultConnection = defaultConnectionString); + var connectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test1;" + }; + _services.Configure(option => option.ConnectionStrings = connectionStrings); var unitOfWorkAccessor = _services.BuildServiceProvider().GetService()!; var options = _services.BuildServiceProvider().GetRequiredService>(); var provider = new DefaultDbIsolationConnectionStringProvider(unitOfWorkAccessor, options); - Assert.IsTrue(await provider.GetConnectionStringAsync() == defaultConnectionString); + Assert.IsTrue(await provider.GetConnectionStringAsync() == connectionStrings.DefaultConnection); } [TestMethod] public async Task TestGetConnectionString3Async() { - string defaultConnectionString = "data source=test1;"; - _services.Configure(option => option.DefaultConnection = defaultConnectionString); + var connectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test1;" + }; + _services.Configure(option => option.ConnectionStrings = connectionStrings); var unitOfWorkAccessor = _services.BuildServiceProvider().GetService()!; _services.Configure(option => { - option.DefaultConnection = defaultConnectionString; - option.Isolations = new List + option.ConnectionStrings = connectionStrings; + option.IsolationConnectionStrings = new List { new() { @@ -72,13 +78,16 @@ public async Task TestGetConnectionString3Async() [TestMethod] public async Task TestGetConnectionString4Async() { - string defaultConnectionString = "data source=test1;"; - _services.Configure(option => option.DefaultConnection = defaultConnectionString); + var connectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test1;" + }; + _services.Configure(option => option.ConnectionStrings = connectionStrings); var unitOfWorkAccessor = _services.BuildServiceProvider().GetService()!; _services.Configure(option => { - option.DefaultConnection = defaultConnectionString; - option.Isolations = new List + option.ConnectionStrings = connectionStrings; + option.IsolationConnectionStrings = new List { new() { @@ -103,13 +112,16 @@ public async Task TestGetConnectionString4Async() [TestMethod] public async Task TestGetConnectionString5Async() { - string defaultConnectionString = "data source=test1;"; - _services.Configure(option => option.DefaultConnection = defaultConnectionString); + var connectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test1;" + }; + _services.Configure(option => option.ConnectionStrings = connectionStrings); var unitOfWorkAccessor = _services.BuildServiceProvider().GetService()!; _services.Configure(option => { - option.DefaultConnection = defaultConnectionString; - option.Isolations = new List + option.ConnectionStrings = connectionStrings; + option.IsolationConnectionStrings = new List { new() { @@ -134,13 +146,16 @@ public async Task TestGetConnectionString5Async() [TestMethod] public async Task TestGetConnectionString6Async() { - string defaultConnectionString = "data source=test1;"; - _services.Configure(option => option.DefaultConnection = defaultConnectionString); + var connectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test1;" + }; + _services.Configure(option => option.ConnectionStrings = connectionStrings); var unitOfWorkAccessor = _services.BuildServiceProvider().GetService()!; _services.Configure(option => { - option.DefaultConnection = defaultConnectionString; - option.Isolations = new List + option.ConnectionStrings = connectionStrings; + option.IsolationConnectionStrings = new List { new() { @@ -165,13 +180,16 @@ public async Task TestGetConnectionString6Async() [TestMethod] public async Task TestGetConnectionString7Async() { - string defaultConnectionString = "data source=test1;"; - _services.Configure(option => option.DefaultConnection = defaultConnectionString); + var connectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test1;" + }; + _services.Configure(option => option.ConnectionStrings = connectionStrings); var unitOfWorkAccessor = _services.BuildServiceProvider().GetService()!; _services.Configure(option => { - option.DefaultConnection = defaultConnectionString; - option.Isolations = new List + option.ConnectionStrings = connectionStrings; + option.IsolationConnectionStrings = new List { new() { @@ -196,13 +214,16 @@ public async Task TestGetConnectionString7Async() [TestMethod] public async Task TestGetConnectionString8Async() { - string defaultConnectionString = "data source=test1;"; - _services.Configure(option => option.DefaultConnection = defaultConnectionString); + var connectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test1;" + }; + _services.Configure(option => option.ConnectionStrings = connectionStrings); var unitOfWorkAccessor = _services.BuildServiceProvider().GetService()!; _services.Configure(option => { - option.DefaultConnection = defaultConnectionString; - option.Isolations = new List + option.ConnectionStrings = connectionStrings; + option.IsolationConnectionStrings = new List { new() { @@ -246,13 +267,16 @@ public async Task TestGetConnectionString8Async() [TestMethod] public async Task TestGetConnectionString9Async() { - string defaultConnectionString = "data source=test1;"; - _services.Configure(option => option.DefaultConnection = defaultConnectionString); + var connectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test1;" + }; + _services.Configure(option => option.ConnectionStrings = connectionStrings); var unitOfWorkAccessor = _services.BuildServiceProvider().GetService()!; _services.Configure(option => { - option.DefaultConnection = defaultConnectionString; - option.Isolations = new List + option.ConnectionStrings = connectionStrings; + option.IsolationConnectionStrings = new List { new() { @@ -296,13 +320,16 @@ public async Task TestGetConnectionString9Async() [TestMethod] public async Task TestGetConnectionString10Async() { - string defaultConnectionString = "data source=test1;"; - _services.Configure(option => option.DefaultConnection = defaultConnectionString); + var connectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test1;" + }; + _services.Configure(option => option.ConnectionStrings = connectionStrings); var unitOfWorkAccessor = _services.BuildServiceProvider().GetService()!; _services.Configure(option => { - option.DefaultConnection = defaultConnectionString; - option.Isolations = new List + option.ConnectionStrings = connectionStrings; + option.IsolationConnectionStrings = new List { new() { @@ -346,13 +373,16 @@ public async Task TestGetConnectionString10Async() [TestMethod] public async Task TestGetConnectionString11Async() { - string defaultConnectionString = "data source=test1;"; - _services.Configure(option => option.DefaultConnection = defaultConnectionString); + var connectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test1;" + }; + _services.Configure(option => option.ConnectionStrings = connectionStrings); var unitOfWorkAccessor = _services.BuildServiceProvider().GetService()!; _services.Configure(option => { - option.DefaultConnection = defaultConnectionString; - option.Isolations = new List + option.ConnectionStrings = connectionStrings; + option.IsolationConnectionStrings = new List { new() { @@ -388,7 +418,8 @@ public async Task TestGetConnectionString11Async() Mock tenantContext = new(); tenantContext.Setup(context => context.CurrentTenant).Returns(new Tenant("2")).Verifiable(); - var provider = new DefaultDbIsolationConnectionStringProvider(unitOfWorkAccessor, options, environmentContext.Object, tenantContext.Object); + var provider = + new DefaultDbIsolationConnectionStringProvider(unitOfWorkAccessor, options, environmentContext.Object, tenantContext.Object); Assert.IsTrue(await provider.GetConnectionStringAsync() == "data source=test4;"); } @@ -396,13 +427,16 @@ public async Task TestGetConnectionString11Async() public async Task TestGetConnectionString12Async() { _services.AddLogging(); - string defaultConnectionString = "data source=test1;"; - _services.Configure(option => option.DefaultConnection = defaultConnectionString); + var connectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test1;" + }; + _services.Configure(option => option.ConnectionStrings = connectionStrings); var unitOfWorkAccessor = _services.BuildServiceProvider().GetService()!; _services.Configure(option => { - option.DefaultConnection = defaultConnectionString; - option.Isolations = new List + option.ConnectionStrings = connectionStrings; + option.IsolationConnectionStrings = new List { new() { @@ -438,20 +472,24 @@ public async Task TestGetConnectionString12Async() Mock tenantContext = new(); tenantContext.Setup(context => context.CurrentTenant).Returns(new Tenant("2")).Verifiable(); - var provider = new DefaultDbIsolationConnectionStringProvider(unitOfWorkAccessor, options, environmentContext.Object, tenantContext.Object); + var provider = + new DefaultDbIsolationConnectionStringProvider(unitOfWorkAccessor, options, environmentContext.Object, tenantContext.Object); Assert.IsTrue(await provider.GetConnectionStringAsync() == "data source=test4;"); } [TestMethod] public async Task TestGetConnectionString13Async() { - string defaultConnectionString = "data source=test1;"; - _services.Configure(option => option.DefaultConnection = defaultConnectionString); + var connectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test1;" + }; + _services.Configure(option => option.ConnectionStrings = connectionStrings); var unitOfWorkAccessor = _services.BuildServiceProvider().GetService()!; _services.Configure(option => { - option.DefaultConnection = defaultConnectionString; - option.Isolations = new List + option.ConnectionStrings = connectionStrings; + option.IsolationConnectionStrings = new List { new() { diff --git a/test/Masa.Contrib.Isolation.Tests/TestIsolation.cs b/test/Masa.Contrib.Isolation.Tests/TestIsolation.cs index 01f512dba..e112f6d2d 100644 --- a/test/Masa.Contrib.Isolation.Tests/TestIsolation.cs +++ b/test/Masa.Contrib.Isolation.Tests/TestIsolation.cs @@ -12,8 +12,11 @@ public void TestGetDbContextOptionsList() var services = new ServiceCollection(); services.Configure(option => { - option.DefaultConnection = "data source=test2"; - option.Isolations = new() + option.ConnectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test2" + }; + option.IsolationConnectionStrings = new() { new() { @@ -107,7 +110,7 @@ public void TestUseIsolation6() options.Setup(option => option.Services).Returns(services).Verifiable(); options.Object.UseIsolation(isolationBuilder => isolationBuilder.UseMultiEnvironment()); var serviceProvider = services.BuildServiceProvider(); - Assert.IsTrue(services.Count(service => service.ServiceType == typeof(IIsolationDbConnectionStringProvider)) == 1); + Assert.IsTrue(services.Count(service => service.ServiceType == typeof(IIsolationMiddleware)) == 1); Assert.IsTrue(serviceProvider.GetServices().Count() == 1); Assert.IsTrue(!serviceProvider.GetServices().Any()); @@ -123,7 +126,7 @@ public void TestUseIsolation7() options.Object.UseIsolation(isolationBuilder => isolationBuilder.UseMultiTenant()); var serviceProvider = services.BuildServiceProvider(); - Assert.IsTrue(services.Count(service => service.ServiceType == typeof(IIsolationDbConnectionStringProvider)) == 1); + Assert.IsTrue(services.Count(service => service.ServiceType == typeof(IIsolationMiddleware)) == 1); Assert.IsTrue(!serviceProvider.GetServices().Any()); Assert.IsTrue(serviceProvider.GetServices().Count() == 1); @@ -141,7 +144,7 @@ public void TestUseIsolation8() => isolationBuilder.UseMultiTenant().UseMultiEnvironment()); var serviceProvider = services.BuildServiceProvider(); - Assert.IsTrue(services.Count(service => service.ServiceType == typeof(IIsolationDbConnectionStringProvider)) == 1); + Assert.IsTrue(services.Count(service => service.ServiceType == typeof(IIsolationMiddleware)) == 1); Assert.IsTrue(serviceProvider.GetServices().Count() == 1); Assert.IsTrue(serviceProvider.GetServices().Count() == 1); diff --git a/test/Masa.Contrib.Isolation.Tests/TestParserProvider.cs b/test/Masa.Contrib.Isolation.Tests/TestParserProvider.cs index a88c61e87..6e49fdb35 100644 --- a/test/Masa.Contrib.Isolation.Tests/TestParserProvider.cs +++ b/test/Masa.Contrib.Isolation.Tests/TestParserProvider.cs @@ -374,23 +374,4 @@ public async Task TestEnvironmentVariablesParserAsync() Assert.IsTrue(environmentVariablesParserProvider.Name == "EnvironmentVariables"); Assert.IsTrue(handler); } - - [TestMethod] - public async Task TestEnvironmentVariablesParser2Async() - { - var services = new ServiceCollection(); - Mock environmentSetter = new(); - string environmentKey = "env"; - System.Environment.SetEnvironmentVariable(environmentKey, ""); - environmentSetter.Setup(setter => setter.SetEnvironment(It.IsAny())).Verifiable(); - services.AddScoped(_ => environmentSetter.Object); - services.Configure(option => - { - option.EnvironmentKey = environmentKey; - }); - var serviceProvider = services.BuildServiceProvider(); - var environmentVariablesParserProvider = new EnvironmentVariablesParserProvider(); - var handler = await environmentVariablesParserProvider.ResolveAsync(serviceProvider, environmentKey, _ => { }); - Assert.IsFalse(handler); - } } diff --git a/test/Masa.Contrib.Isolation.Tests/UnitOfWorkAccessor.cs b/test/Masa.Contrib.Isolation.Tests/UnitOfWorkAccessor.cs index e16da621f..2b9d6c1d2 100644 --- a/test/Masa.Contrib.Isolation.Tests/UnitOfWorkAccessor.cs +++ b/test/Masa.Contrib.Isolation.Tests/UnitOfWorkAccessor.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +using Masa.BuildingBlocks.Data.Options; + namespace Masa.Contrib.Isolation.Tests; public class UnitOfWorkAccessor: IUnitOfWorkAccessor diff --git a/test/Masa.Contrib.Isolation.Tests/_Imports.cs b/test/Masa.Contrib.Isolation.Tests/_Imports.cs index 241d1e6a5..d4f836802 100644 --- a/test/Masa.Contrib.Isolation.Tests/_Imports.cs +++ b/test/Masa.Contrib.Isolation.Tests/_Imports.cs @@ -2,7 +2,6 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. global using Masa.BuildingBlocks.Data.UoW; -global using Masa.BuildingBlocks.Data.UoW.Options; global using Masa.BuildingBlocks.Dispatcher.Events; global using Masa.BuildingBlocks.Isolation; global using Masa.BuildingBlocks.Isolation.Environment; @@ -20,3 +19,6 @@ global using Moq; global using System; global using System.Linq; +global using Masa.BuildingBlocks.Data; +global using Masa.BuildingBlocks.Data.Options; +global using Masa.BuildingBlocks.Isolation.Middleware; diff --git a/test/Masa.Contrib.Isolation.UoW.EF.Tests/Masa.Contrib.Isolation.UoW.EF.Tests.csproj b/test/Masa.Contrib.Isolation.UoW.EF.Tests/Masa.Contrib.Isolation.UoW.EF.Tests.csproj index fd4f337c4..0ff528134 100644 --- a/test/Masa.Contrib.Isolation.UoW.EF.Tests/Masa.Contrib.Isolation.UoW.EF.Tests.csproj +++ b/test/Masa.Contrib.Isolation.UoW.EF.Tests/Masa.Contrib.Isolation.UoW.EF.Tests.csproj @@ -20,11 +20,11 @@ - + diff --git a/test/Masa.Contrib.Isolation.UoW.EF.Tests/TestIsolation.cs b/test/Masa.Contrib.Isolation.UoW.EF.Tests/TestIsolation.cs index 3e7b9b40f..1009da268 100644 --- a/test/Masa.Contrib.Isolation.UoW.EF.Tests/TestIsolation.cs +++ b/test/Masa.Contrib.Isolation.UoW.EF.Tests/TestIsolation.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +using Masa.BuildingBlocks.Data; + namespace Masa.Contrib.Isolation.UoW.EF.Tests; [TestClass] @@ -178,8 +180,11 @@ public void TestUseMultiEnvironment() { _services.Configure(option => { - option.DefaultConnection = "data source=test4"; - option.Isolations = new List + option.ConnectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test4" + }; + option.IsolationConnectionStrings = new List { new() { @@ -229,8 +234,11 @@ public void TestUseMultiTenant() { _services.Configure(option => { - option.DefaultConnection = "data source=test7"; - option.Isolations = new List + option.ConnectionStrings = new ConnectionStrings() + { + DefaultConnection = "data source=test7" + }; + option.IsolationConnectionStrings = new List { new() { diff --git a/test/Masa.Contrib.Isolation.UoW.EF.Tests/_Imports.cs b/test/Masa.Contrib.Isolation.UoW.EF.Tests/_Imports.cs index a2134c240..8f68488b0 100644 --- a/test/Masa.Contrib.Isolation.UoW.EF.Tests/_Imports.cs +++ b/test/Masa.Contrib.Isolation.UoW.EF.Tests/_Imports.cs @@ -7,10 +7,10 @@ global using Masa.BuildingBlocks.Isolation.MultiTenant; global using Masa.BuildingBlocks.Isolation.Options; global using Masa.Contrib.Configuration; +global using Masa.Contrib.Data.EntityFrameworkCore; +global using Masa.Contrib.Data.EntityFrameworkCore.Sqlite; global using Masa.Contrib.Isolation.MultiEnvironment; global using Masa.Contrib.Isolation.MultiTenant; -global using Masa.Utils.Data.EntityFrameworkCore; -global using Masa.Utils.Data.EntityFrameworkCore.Sqlite; global using Microsoft.AspNetCore.Builder; global using Microsoft.Data.Sqlite; global using Microsoft.EntityFrameworkCore; @@ -22,4 +22,3 @@ global using System; global using System.IO; global using System.Linq; - diff --git a/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/Masa.Contrib.Isolation.UoW.EF.Web.Tests.csproj b/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/Masa.Contrib.Isolation.UoW.EF.Web.Tests.csproj index b585f216c..368e33e1f 100644 --- a/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/Masa.Contrib.Isolation.UoW.EF.Web.Tests.csproj +++ b/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/Masa.Contrib.Isolation.UoW.EF.Web.Tests.csproj @@ -13,10 +13,10 @@ - + diff --git a/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/_Imports.cs b/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/_Imports.cs index 96e1bd51e..5eb3faaca 100644 --- a/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/_Imports.cs +++ b/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/_Imports.cs @@ -1,16 +1,16 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Masa.BuildingBlocks.Data.Contracts.DataFiltering; global using Masa.BuildingBlocks.Dispatcher.Events; global using Masa.BuildingBlocks.Isolation; global using Masa.BuildingBlocks.Isolation.Environment; +global using Masa.Contrib.Data.EntityFrameworkCore; +global using Masa.Contrib.Data.EntityFrameworkCore.Sqlite; global using Masa.Contrib.Dispatcher.Events; global using Masa.Contrib.Isolation.MultiEnvironment; global using Masa.Contrib.Isolation.MultiTenant; global using Masa.Contrib.Isolation.UoW.EF.Web.Tests.Events; -global using Masa.Utils.Data.EntityFrameworkCore; -global using Masa.Utils.Data.EntityFrameworkCore.Filters; -global using Masa.Utils.Data.EntityFrameworkCore.Sqlite; global using Masa.Utils.Security.Cryptography; global using Microsoft.AspNetCore.Http; global using Microsoft.Data.Sqlite; @@ -23,4 +23,3 @@ global using System.Collections.Generic; global using System.IO; global using System.Threading.Tasks; - From 9dc9f05a3febf344a0ff33dad1d105d9162f1ec1 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 9 May 2022 17:03:50 +0800 Subject: [PATCH 03/10] refactor(SoftDelete): Refactor soft delete --- Masa.Contrib.sln | 12 ++++ src/BuildingBlocks/MASA.BuildingBlocks | 2 +- .../DataFiltering/DataFilter.cs | 71 +++++++++++++++++++ .../SoftDeleteSaveChangesFilter.cs | 4 +- .../Internal/DataFilterState.cs | 14 ++++ .../Internal/DisposeAction.cs | 13 ++++ .../Internal/InstanceBuilder.cs | 2 +- .../Internal/NullDisposable.cs | 13 ++++ .../Masa.Contrib.Data.Contracts.EF.csproj | 1 + .../MasaDbContextOptionsBuilderExtensions.cs | 26 +++++-- .../Options/FilterOptions.cs | 2 +- .../_Imports.cs | 3 +- .../MasaDbContextOptionsBuilderExtensions.cs | 46 ++++++++++-- .../_Imports.cs | 7 +- .../MasaDbContextOptionsBuilderExtensions.cs | 24 ++++++- .../MasaDbContextOptionsBuilderExtensions.cs | 40 +++++++++-- .../_Imports.cs | 2 +- .../MasaDbContextOptionsBuilderExtensions.cs | 40 +++++++++-- .../_Imports.cs | 2 +- .../MasaDbContextOptionsBuilderExtensions.cs | 44 ++++++++++-- .../_Imports.cs | 2 +- .../MasaDbContextOptionsBuilderExtensions.cs | 40 +++++++++-- .../_Imports.cs | 2 +- .../MasaDbContextOptionsBuilderExtensions.cs | 42 +++++++++-- .../_Imports.cs | 2 +- .../MasaDbContextOptionsBuilderExtensions.cs | 40 +++++++++-- .../_Imports.cs | 2 +- .../DefaultConnectionStringProvider.cs | 3 + .../EFDbContextOptionsBuilder.cs | 8 +-- .../EFDbContextOptionsBuilder`.cs | 7 +- .../Filters/ISaveChangesFilter.cs | 3 + .../IModelCreatingProvider.cs | 5 +- ...sa.Contrib.Data.EntityFrameworkCore.csproj | 4 -- .../MasaDbContext.cs | 3 + .../MasaDbContextOptions.cs | 3 + .../MasaDbContextOptionsBuilder.cs | 2 +- .../MasaDbContextOptions`.cs | 4 +- .../README.md | 2 +- .../README.zh-CN.md | 3 +- .../ServiceCollectionExtensions.cs | 5 +- .../_Imports.cs | 3 + .../Internal/Const.cs | 2 +- src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs | 9 +-- .../Masa.Contrib.Isolation.UoW.EF/README.md | 33 ++++----- .../README.zh-CN.md | 33 ++++----- 45 files changed, 516 insertions(+), 114 deletions(-) create mode 100644 src/Data/Masa.Contrib.Data.Contracts.EF/DataFiltering/DataFilter.cs rename src/Data/Masa.Contrib.Data.Contracts.EF/{Filters => DataFiltering}/SoftDeleteSaveChangesFilter.cs (95%) create mode 100644 src/Data/Masa.Contrib.Data.Contracts.EF/Internal/DataFilterState.cs create mode 100644 src/Data/Masa.Contrib.Data.Contracts.EF/Internal/DisposeAction.cs create mode 100644 src/Data/Masa.Contrib.Data.Contracts.EF/Internal/NullDisposable.cs diff --git a/Masa.Contrib.sln b/Masa.Contrib.sln index 209527235..33a587ed1 100644 --- a/Masa.Contrib.sln +++ b/Masa.Contrib.sln @@ -183,6 +183,7 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFrameworkCore", "src\Data\Masa.Contrib.Data.EntityFrameworkCore\Masa.Contrib.Data.EntityFrameworkCore.csproj", "{87DD354D-4D48-4918-ACDE-A7FF62FA0DD8}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.Mapping.Mapster", "src\Data\Mapping\Masa.Contrib.Data.Mapping.Mapster\Masa.Contrib.Data.Mapping.Mapster.csproj", "{D5EA7A25-0FD2-4545-9C1C-FF96E5E35145}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFrameworkCore.Cosmos", "src\Data\Masa.Contrib.Data.EntityFrameworkCore.Cosmos\Masa.Contrib.Data.EntityFrameworkCore.Cosmos.csproj", "{3236F880-3DC0-450F-A14D-8C87525845DD}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFrameworkCore.InMemory", "src\Data\Masa.Contrib.Data.EntityFrameworkCore.InMemory\Masa.Contrib.Data.EntityFrameworkCore.InMemory.csproj", "{7E3FAE39-9CD1-46FA-A389-660008035DFB}" @@ -199,6 +200,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFra EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFrameworkCore.SqlServer", "src\Data\Masa.Contrib.Data.EntityFrameworkCore.SqlServer\Masa.Contrib.Data.EntityFrameworkCore.SqlServer.csproj", "{E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.Data.EntityFrameworkCore.Tests", "test\Masa.Contrib.Data.EntityFrameworkCore.Tests\Masa.Contrib.Data.EntityFrameworkCore.Tests.csproj", "{E1096C8E-6EC1-45CB-9CA6-0ADD830CAAA3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -807,6 +810,14 @@ Global {E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE}.Release|Any CPU.Build.0 = Release|Any CPU {E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE}.Release|x64.ActiveCfg = Release|Any CPU {E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE}.Release|x64.Build.0 = Release|Any CPU + {E1096C8E-6EC1-45CB-9CA6-0ADD830CAAA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E1096C8E-6EC1-45CB-9CA6-0ADD830CAAA3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E1096C8E-6EC1-45CB-9CA6-0ADD830CAAA3}.Debug|x64.ActiveCfg = Debug|Any CPU + {E1096C8E-6EC1-45CB-9CA6-0ADD830CAAA3}.Debug|x64.Build.0 = Debug|Any CPU + {E1096C8E-6EC1-45CB-9CA6-0ADD830CAAA3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E1096C8E-6EC1-45CB-9CA6-0ADD830CAAA3}.Release|Any CPU.Build.0 = Release|Any CPU + {E1096C8E-6EC1-45CB-9CA6-0ADD830CAAA3}.Release|x64.ActiveCfg = Release|Any CPU + {E1096C8E-6EC1-45CB-9CA6-0ADD830CAAA3}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -906,6 +917,7 @@ Global {A50DC3FB-FD2A-4EF8-8333-4782DFFF0BF1} = {E33ADF54-4D35-49B7-BDA6-412587CA39FF} {C8CE5B92-96A6-4FA1-9EEB-43A524DC54AA} = {E33ADF54-4D35-49B7-BDA6-412587CA39FF} {E337EE1A-F6DB-4276-9CD6-DEBF224D7FDE} = {E33ADF54-4D35-49B7-BDA6-412587CA39FF} + {E1096C8E-6EC1-45CB-9CA6-0ADD830CAAA3} = {38E6C400-90C0-493E-9266-C1602E229F1B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03} diff --git a/src/BuildingBlocks/MASA.BuildingBlocks b/src/BuildingBlocks/MASA.BuildingBlocks index e15b73b4f..d3b46ae3d 160000 --- a/src/BuildingBlocks/MASA.BuildingBlocks +++ b/src/BuildingBlocks/MASA.BuildingBlocks @@ -1 +1 @@ -Subproject commit e15b73b4fc205165bf809cb0564ee454ee3b70f5 +Subproject commit d3b46ae3d38a9892672725aec7e46af528cdeb01 diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/DataFiltering/DataFilter.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/DataFiltering/DataFilter.cs new file mode 100644 index 000000000..1e365be22 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/DataFiltering/DataFilter.cs @@ -0,0 +1,71 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.Contracts.EF.DataFiltering; + +public class DataFilter : IDataFilter +{ + private readonly IServiceProvider _serviceProvider; + private readonly MemoryCache _cache; + + public DataFilter(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + _cache = new(); + } + + public IDisposable Enable() where TFilter : class + => GetFilter().Enable(); + + public IDisposable Disable() where TFilter : class + => GetFilter().Disable(); + + public bool IsEnabled() where TFilter : class + => GetFilter().Enabled; + + private DataFilter GetFilter() + where TFilter : class + { + return (_cache.GetOrAdd( + typeof(TFilter), + _ => _serviceProvider.GetRequiredService>() + ) as DataFilter)!; + } +} + +public class DataFilter where TFilter : class +{ + private readonly AsyncLocal _filter; + + public DataFilter() => _filter = new AsyncLocal(); + + public bool Enabled + { + get + { + _filter.Value ??= new DataFilterState(true); + + return _filter.Value!.Enabled; + } + } + + public IDisposable Enable() + { + if (Enabled) + return NullDisposable.Instance; + + _filter.Value!.Enabled = true; + + return new DisposeAction(() => Disable()); + } + + public IDisposable Disable() + { + if (!Enabled) + return NullDisposable.Instance; + + _filter.Value!.Enabled = false; + + return new DisposeAction(() => Enable()); + } +} diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/Filters/SoftDeleteSaveChangesFilter.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/DataFiltering/SoftDeleteSaveChangesFilter.cs similarity index 95% rename from src/Data/Masa.Contrib.Data.Contracts.EF/Filters/SoftDeleteSaveChangesFilter.cs rename to src/Data/Masa.Contrib.Data.Contracts.EF/DataFiltering/SoftDeleteSaveChangesFilter.cs index 138e43dbc..d0bf90987 100644 --- a/src/Data/Masa.Contrib.Data.Contracts.EF/Filters/SoftDeleteSaveChangesFilter.cs +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/DataFiltering/SoftDeleteSaveChangesFilter.cs @@ -1,7 +1,7 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -namespace Masa.Contrib.Data.Contracts.EF.Filters; +namespace Masa.Contrib.Data.Contracts.EF.DataFiltering; public class SoftDeleteSaveChangesFilter : ISaveChangesFilter where TDbContext : DbContext { diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/DataFilterState.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/DataFilterState.cs new file mode 100644 index 000000000..85364dfa7 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/DataFilterState.cs @@ -0,0 +1,14 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.Contracts.EF.Internal; + +internal class DataFilterState +{ + public bool Enabled { get; set; } + + public DataFilterState(bool enabled) + { + Enabled = enabled; + } +} diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/DisposeAction.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/DisposeAction.cs new file mode 100644 index 000000000..2c179575d --- /dev/null +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/DisposeAction.cs @@ -0,0 +1,13 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.Contracts.EF.Internal; + +internal class DisposeAction : IDisposable +{ + private readonly Action _action; + + public DisposeAction(Action action) => _action = action; + + public void Dispose() => _action.Invoke(); +} diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/InstanceBuilder.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/InstanceBuilder.cs index 170344c6b..f4a9606fe 100644 --- a/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/InstanceBuilder.cs +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/InstanceBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. namespace Masa.Contrib.Data.Contracts.EF.Internal; diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/NullDisposable.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/NullDisposable.cs new file mode 100644 index 000000000..ad67a3355 --- /dev/null +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/Internal/NullDisposable.cs @@ -0,0 +1,13 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.Contracts.EF.Internal; + +internal class NullDisposable : IDisposable +{ + public static NullDisposable Instance { get; } = new(); + + public void Dispose() + { + } +} diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/Masa.Contrib.Data.Contracts.EF.csproj b/src/Data/Masa.Contrib.Data.Contracts.EF/Masa.Contrib.Data.Contracts.EF.csproj index 7cc463950..88848785d 100644 --- a/src/Data/Masa.Contrib.Data.Contracts.EF/Masa.Contrib.Data.Contracts.EF.csproj +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/Masa.Contrib.Data.Contracts.EF.csproj @@ -12,6 +12,7 @@ + diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/MasaDbContextOptionsBuilderExtensions.cs index d6df464cc..5b222256c 100644 --- a/src/Data/Masa.Contrib.Data.Contracts.EF/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/MasaDbContextOptionsBuilderExtensions.cs @@ -10,6 +10,17 @@ public static class MasaDbContextOptionsBuilderExtensions public static MasaDbContextOptionsBuilder UseFilter( this MasaDbContextOptionsBuilder masaDbContextOptionsBuilder, Action? options = null) + => masaDbContextOptionsBuilder.UseFilterCore(false, options); + + public static MasaDbContextOptionsBuilder UseTestFilter( + this MasaDbContextOptionsBuilder masaDbContextOptionsBuilder, + Action? options = null) + => masaDbContextOptionsBuilder.UseFilterCore(true, options); + + private static MasaDbContextOptionsBuilder UseFilterCore( + this MasaDbContextOptionsBuilder masaDbContextOptionsBuilder, + bool isTest, + Action? options = null) { var filterOptions = new FilterOptions(); options?.Invoke(filterOptions); @@ -17,17 +28,20 @@ public static MasaDbContextOptionsBuilder UseFilter( masaDbContextOptionsBuilder.Services.TryAddScoped(typeof(DataFilter<>)); masaDbContextOptionsBuilder.Services.TryAddScoped(); - if (filterOptions.EnableSoftDelete) masaDbContextOptionsBuilder.UseSoftDelete(); + if (filterOptions.EnableSoftDelete) masaDbContextOptionsBuilder.UseSoftDelete(isTest); return masaDbContextOptionsBuilder; } - private static void UseSoftDelete(this MasaDbContextOptionsBuilder masaDbContextOptionsBuilder) + private static void UseSoftDelete(this MasaDbContextOptionsBuilder masaDbContextOptionsBuilder, bool isTest = false) { - if (_types.Any(type => masaDbContextOptionsBuilder.DbContextType == type)) - return; + if (!isTest) + { + if (_types.Any(type => masaDbContextOptionsBuilder.DbContextType == type)) + return; - _types.Add(masaDbContextOptionsBuilder.DbContextType); + _types.Add(masaDbContextOptionsBuilder.DbContextType); + } var masaDbContextOptionsType = typeof(MasaDbContextOptions<>).MakeGenericType(masaDbContextOptionsBuilder.DbContextType); var softDeleteSaveChangesFilterType = @@ -39,7 +53,7 @@ private static void UseSoftDelete(this MasaDbContextOptionsBuilder masaDbContext new ServiceDescriptor(typeof(ISaveChangesFilter), serviceProvider => { - var instance= invokeDelegate.Invoke( + var instance = invokeDelegate.Invoke( serviceProvider.GetRequiredService(masaDbContextOptionsType), serviceProvider.GetRequiredService(masaDbContextOptionsBuilder.DbContextType)); return instance; diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/Options/FilterOptions.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/Options/FilterOptions.cs index 43a11515d..d9d92f32d 100644 --- a/src/Data/Masa.Contrib.Data.Contracts.EF/Options/FilterOptions.cs +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/Options/FilterOptions.cs @@ -1,4 +1,4 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. namespace Masa.Contrib.Data.Contracts.EF.Options; diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/_Imports.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/_Imports.cs index 82f53b576..9ce9652cb 100644 --- a/src/Data/Masa.Contrib.Data.Contracts.EF/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/_Imports.cs @@ -2,11 +2,12 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. global using Masa.BuildingBlocks.Data.Contracts.DataFiltering; -global using Masa.Contrib.Data.Contracts.EF.Filters; +global using Masa.Contrib.Data.Contracts.EF.DataFiltering; global using Masa.Contrib.Data.Contracts.EF.Internal; global using Masa.Contrib.Data.Contracts.EF.Options; global using Masa.Contrib.Data.EntityFrameworkCore; global using Masa.Contrib.Data.EntityFrameworkCore.Filters; +global using Masa.Utils.Caching.Memory; global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.ChangeTracking; global using Microsoft.EntityFrameworkCore.Metadata; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/MasaDbContextOptionsBuilderExtensions.cs index a66edf49f..42702bb35 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/MasaDbContextOptionsBuilderExtensions.cs @@ -40,11 +40,27 @@ public static MasaDbContextOptionsBuilder UseCosmos( string accountKey, string databaseName, Action? cosmosOptionsAction = null) + => builder.UseCosmosCore(accountEndpoint, accountKey, databaseName, false, cosmosOptionsAction); + + public static MasaDbContextOptionsBuilder UseTestCosmos( + this MasaDbContextOptionsBuilder builder, + string accountEndpoint, + string accountKey, + string databaseName, + Action? cosmosOptionsAction = null) + => builder.UseCosmosCore(accountEndpoint, accountKey, databaseName, true, cosmosOptionsAction); + + private static MasaDbContextOptionsBuilder UseCosmosCore( + this MasaDbContextOptionsBuilder builder, + string accountEndpoint, + string accountKey, + string databaseName, + bool isTest, + Action? cosmosOptionsAction = null) { - builder.UseCosmosCore($"AccountEndpoint={accountEndpoint};AccountKey={accountKey};Database={databaseName};"); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseCosmos(accountEndpoint, accountKey, databaseName, cosmosOptionsAction); - return builder; + return builder.UseCosmosCore($"AccountEndpoint={accountEndpoint};AccountKey={accountKey};Database={databaseName};"); } public static MasaDbContextOptionsBuilder UseCosmos( @@ -52,17 +68,37 @@ public static MasaDbContextOptionsBuilder UseCosmos( string connectionString, string databaseName, Action? cosmosOptionsAction = null) + => builder.UseCosmosCore(connectionString, databaseName, false, cosmosOptionsAction); + + public static MasaDbContextOptionsBuilder UseTestCosmos( + this MasaDbContextOptionsBuilder builder, + string connectionString, + string databaseName, + Action? cosmosOptionsAction = null) + => builder.UseCosmosCore(connectionString, databaseName, true, cosmosOptionsAction); + + private static MasaDbContextOptionsBuilder UseCosmosCore( + this MasaDbContextOptionsBuilder builder, + string connectionString, + string databaseName, + bool isTest, + Action? cosmosOptionsAction = null) { - builder.UseCosmosCore($"{connectionString};Database={databaseName};"); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseCosmos(connectionString, databaseName, cosmosOptionsAction); - return builder; + return builder.UseCosmosCore($"{connectionString};Database={databaseName};", isTest); } - private static MasaDbContextOptionsBuilder UseCosmosCore(this MasaDbContextOptionsBuilder builder, string connectionString) + private static MasaDbContextOptionsBuilder UseCosmosCore( + this MasaDbContextOptionsBuilder builder, + string connectionString, + bool isTest = false) { var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + if (!isTest && dbConnectionOptions.ConnectionStrings.ContainsKey(name)) + throw new ArgumentException($"The [{builder.DbContextType.Name}] Database Connection String already exists"); + dbConnectionOptions.TryAddConnectionString(name, connectionString); return builder; } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/_Imports.cs index 12126d9f4..aab4fdb17 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/_Imports.cs @@ -1,6 +1,9 @@ -global using Masa.Contrib.Data.EntityFrameworkCore.Cosmos.Internal; +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Data; +global using Masa.Contrib.Data.EntityFrameworkCore.Cosmos.Internal; global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.Infrastructure; global using Microsoft.Extensions.DependencyInjection; -global using Masa.BuildingBlocks.Data; global using Microsoft.Extensions.Options; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/MasaDbContextOptionsBuilderExtensions.cs index d3dccb041..26e934224 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/MasaDbContextOptionsBuilderExtensions.cs @@ -24,17 +24,35 @@ public static MasaDbContextOptionsBuilder UseInMemoryDatabase( this MasaDbContextOptionsBuilder builder, string databaseName, Action? inMemoryOptionsAction = null) + => builder.UseInMemoryDatabaseCore(databaseName, false, inMemoryOptionsAction); + + public static MasaDbContextOptionsBuilder UseInMemoryTestDatabase( + this MasaDbContextOptionsBuilder builder, + string databaseName, + Action? inMemoryOptionsAction = null) + => builder.UseInMemoryDatabaseCore(databaseName, true, inMemoryOptionsAction); + + private static MasaDbContextOptionsBuilder UseInMemoryDatabaseCore( + this MasaDbContextOptionsBuilder builder, + string databaseName, + bool isTest, + Action? inMemoryOptionsAction) { - builder.UseInMemoryDatabaseCore(databaseName); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseInMemoryDatabase(databaseName, inMemoryOptionsAction); - return builder; + return builder.UseInMemoryDatabaseCore(databaseName, isTest); } - private static MasaDbContextOptionsBuilder UseInMemoryDatabaseCore(this MasaDbContextOptionsBuilder builder, string databaseName) + private static MasaDbContextOptionsBuilder UseInMemoryDatabaseCore( + this MasaDbContextOptionsBuilder builder, + string databaseName, + bool isTest = false) { var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + if (!isTest && dbConnectionOptions.ConnectionStrings.ContainsKey(name)) + throw new ArgumentException($"The [{builder.DbContextType.Name}] Database Connection String already exists"); + dbConnectionOptions.TryAddConnectionString(name, databaseName); return builder; } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/MasaDbContextOptionsBuilderExtensions.cs index 39ead98cb..cfe8f851c 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/MasaDbContextOptionsBuilderExtensions.cs @@ -24,27 +24,57 @@ public static MasaDbContextOptionsBuilder UseMySQL( this MasaDbContextOptionsBuilder builder, string connectionString, Action? mySqlOptionsAction = null) + => builder.UseMySQLCore(connectionString, false, mySqlOptionsAction); + + public static MasaDbContextOptionsBuilder UseTestMySQL( + this MasaDbContextOptionsBuilder builder, + string connectionString, + Action? mySqlOptionsAction = null) + => builder.UseMySQLCore(connectionString, true, mySqlOptionsAction); + + private static MasaDbContextOptionsBuilder UseMySQLCore( + this MasaDbContextOptionsBuilder builder, + string connectionString, + bool isTest, + Action? mySqlOptionsAction) { - builder.UseMySQLCore(connectionString); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseMySQL(connectionString, mySqlOptionsAction); - return builder; + return builder.UseMySQLCore(connectionString, isTest); } public static MasaDbContextOptionsBuilder UseMySQL( this MasaDbContextOptionsBuilder builder, DbConnection connection, Action? mySqlOptionsAction = null) + => builder.UseMySQLCore(connection, false, mySqlOptionsAction); + + public static MasaDbContextOptionsBuilder UseTestMySQL( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + Action? mySqlOptionsAction = null) + => builder.UseMySQLCore(connection, true, mySqlOptionsAction); + + private static MasaDbContextOptionsBuilder UseMySQLCore( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + bool isTest, + Action? mySqlOptionsAction = null) { - builder.UseMySQLCore(connection.ConnectionString); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseMySQL(connection, mySqlOptionsAction); - return builder; + return builder.UseMySQLCore(connection.ConnectionString, isTest); } - private static MasaDbContextOptionsBuilder UseMySQLCore(this MasaDbContextOptionsBuilder builder, string connectionString) + private static MasaDbContextOptionsBuilder UseMySQLCore( + this MasaDbContextOptionsBuilder builder, + string connectionString, + bool isTest = false) { var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + if (!isTest && dbConnectionOptions.ConnectionStrings.ContainsKey(name)) + throw new ArgumentException($"The [{builder.DbContextType.Name}] Database Connection String already exists"); + dbConnectionOptions.TryAddConnectionString(name, connectionString); return builder; } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/_Imports.cs index bb60991d6..686d0e2ae 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/_Imports.cs @@ -4,6 +4,6 @@ global using Masa.BuildingBlocks.Data; global using Microsoft.EntityFrameworkCore; global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Options; global using MySql.EntityFrameworkCore.Infrastructure; global using System.Data.Common; -global using Microsoft.Extensions.Options; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/MasaDbContextOptionsBuilderExtensions.cs index 2141360b4..f9afa2a6b 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/MasaDbContextOptionsBuilderExtensions.cs @@ -24,27 +24,57 @@ public static MasaDbContextOptionsBuilder UseOracle( this MasaDbContextOptionsBuilder builder, string connectionString, Action? oracleOptionsAction = null) + => builder.UseOracleCore(connectionString, false, oracleOptionsAction); + + public static MasaDbContextOptionsBuilder UseTestOracle( + this MasaDbContextOptionsBuilder builder, + string connectionString, + Action? oracleOptionsAction = null) + => builder.UseOracleCore(connectionString, true, oracleOptionsAction); + + private static MasaDbContextOptionsBuilder UseOracleCore( + this MasaDbContextOptionsBuilder builder, + string connectionString, + bool isTest, + Action? oracleOptionsAction) { - builder.UseOracleCore(connectionString); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseOracle(connectionString, oracleOptionsAction); - return builder; + return builder.UseOracleCore(connectionString, isTest); } public static MasaDbContextOptionsBuilder UseOracle( this MasaDbContextOptionsBuilder builder, DbConnection connection, Action? oracleOptionsAction = null) + => builder.UseOracleCore(connection, false, oracleOptionsAction); + + public static MasaDbContextOptionsBuilder UseTestOracle( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + Action? oracleOptionsAction = null) + => builder.UseOracleCore(connection, true, oracleOptionsAction); + + private static MasaDbContextOptionsBuilder UseOracleCore( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + bool isTest = false, + Action? oracleOptionsAction = null) { - builder.UseOracleCore(connection.ConnectionString); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseOracle(connection, oracleOptionsAction); - return builder; + return builder.UseOracleCore(connection.ConnectionString, isTest); } - private static MasaDbContextOptionsBuilder UseOracleCore(this MasaDbContextOptionsBuilder builder, string connectionString) + private static MasaDbContextOptionsBuilder UseOracleCore( + this MasaDbContextOptionsBuilder builder, + string connectionString, + bool isTest = false) { var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + if (!isTest && dbConnectionOptions.ConnectionStrings.ContainsKey(name)) + throw new ArgumentException($"The [{builder.DbContextType.Name}] Database Connection String already exists"); + dbConnectionOptions.TryAddConnectionString(name, connectionString); return builder; } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/_Imports.cs index 130409b03..b9b2a72c4 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/_Imports.cs @@ -4,6 +4,6 @@ global using Masa.BuildingBlocks.Data; global using Microsoft.EntityFrameworkCore; global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Options; global using Oracle.EntityFrameworkCore.Infrastructure; global using System.Data.Common; -global using Microsoft.Extensions.Options; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/MasaDbContextOptionsBuilderExtensions.cs index 321bd5d19..3202486db 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/MasaDbContextOptionsBuilderExtensions.cs @@ -27,11 +27,25 @@ public static MasaDbContextOptionsBuilder UseMySql( string connectionString, ServerVersion serverVersion, Action? mySqlOptionsAction = null) + => builder.UseMySqlCore(connectionString, serverVersion, false, mySqlOptionsAction); + + public static MasaDbContextOptionsBuilder UseTestMySql( + this MasaDbContextOptionsBuilder builder, + string connectionString, + ServerVersion serverVersion, + Action? mySqlOptionsAction = null) + => builder.UseMySqlCore(connectionString, serverVersion, true, mySqlOptionsAction); + + private static MasaDbContextOptionsBuilder UseMySqlCore( + this MasaDbContextOptionsBuilder builder, + string connectionString, + ServerVersion serverVersion, + bool isTest, + Action? mySqlOptionsAction = null) { - builder.UseMySqlCore(connectionString); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseMySql(connectionString, serverVersion, mySqlOptionsAction); - return builder; + return builder.UseMySqlCore(connectionString, isTest); } public static MasaDbContextOptionsBuilder UseMySql( @@ -39,16 +53,36 @@ public static MasaDbContextOptionsBuilder UseMySql( DbConnection connection, ServerVersion serverVersion, Action? mySqlOptionsAction = null) + => builder.UseMySqlCore(connection, serverVersion, false, mySqlOptionsAction); + + public static MasaDbContextOptionsBuilder UseTestMySql( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + ServerVersion serverVersion, + Action? mySqlOptionsAction = null) + => builder.UseMySqlCore(connection, serverVersion, true, mySqlOptionsAction); + + private static MasaDbContextOptionsBuilder UseMySqlCore( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + ServerVersion serverVersion, + bool isTest, + Action? mySqlOptionsAction = null) { - builder.UseMySqlCore(connection.ConnectionString); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseMySql(connection, serverVersion, mySqlOptionsAction); - return builder; + return builder.UseMySqlCore(connection.ConnectionString, isTest); } - private static MasaDbContextOptionsBuilder UseMySqlCore(this MasaDbContextOptionsBuilder builder, string connectionString) + private static MasaDbContextOptionsBuilder UseMySqlCore( + this MasaDbContextOptionsBuilder builder, + string connectionString, + bool isTest = false) { var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + if (!isTest && dbConnectionOptions.ConnectionStrings.ContainsKey(name)) + throw new ArgumentException($"The [{builder.DbContextType.Name}] Database Connection String already exists"); + dbConnectionOptions.TryAddConnectionString(name, connectionString); return builder; } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/_Imports.cs index 267a343b6..4bc00c11b 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/_Imports.cs @@ -5,5 +5,5 @@ global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.Infrastructure; global using Microsoft.Extensions.DependencyInjection; -global using System.Data.Common; global using Microsoft.Extensions.Options; +global using System.Data.Common; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/MasaDbContextOptionsBuilderExtensions.cs index a501c20bb..cdde02ef1 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/MasaDbContextOptionsBuilderExtensions.cs @@ -24,27 +24,57 @@ public static MasaDbContextOptionsBuilder UseNpgsql( this MasaDbContextOptionsBuilder builder, string connectionString, Action? npgsqlOptionsAction = null) + => builder.UseNpgsqlCore(connectionString, false, npgsqlOptionsAction); + + public static MasaDbContextOptionsBuilder UseTestNpgsql( + this MasaDbContextOptionsBuilder builder, + string connectionString, + Action? npgsqlOptionsAction = null) + => builder.UseNpgsqlCore(connectionString, true, npgsqlOptionsAction); + + private static MasaDbContextOptionsBuilder UseNpgsqlCore( + this MasaDbContextOptionsBuilder builder, + string connectionString, + bool isTest, + Action? npgsqlOptionsAction) { - builder.UseNpgsqlCore(connectionString); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseNpgsql(connectionString, npgsqlOptionsAction); - return builder; + return builder.UseNpgsqlCore(connectionString, isTest); } public static MasaDbContextOptionsBuilder UseNpgsql( this MasaDbContextOptionsBuilder builder, DbConnection connection, Action? npgsqlOptionsAction = null) + => builder.UseNpgsqlCore(connection, false, npgsqlOptionsAction); + + public static MasaDbContextOptionsBuilder UseTestNpgsql( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + Action? npgsqlOptionsAction = null) + => builder.UseNpgsqlCore(connection, true, npgsqlOptionsAction); + + private static MasaDbContextOptionsBuilder UseNpgsqlCore( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + bool isTest, + Action? npgsqlOptionsAction = null) { - builder.UseNpgsqlCore(connection.ConnectionString); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseNpgsql(connection, npgsqlOptionsAction); - return builder; + return builder.UseNpgsqlCore(connection.ConnectionString, isTest); } - private static MasaDbContextOptionsBuilder UseNpgsqlCore(this MasaDbContextOptionsBuilder builder, string connectionString) + private static MasaDbContextOptionsBuilder UseNpgsqlCore( + this MasaDbContextOptionsBuilder builder, + string connectionString, + bool isTest = false) { var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + if (!isTest && dbConnectionOptions.ConnectionStrings.ContainsKey(name)) + throw new ArgumentException($"The [{builder.DbContextType.Name}] Database Connection String already exists"); + dbConnectionOptions.TryAddConnectionString(name, connectionString); return builder; } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/_Imports.cs index ca567546f..4e2f40e11 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/_Imports.cs @@ -4,6 +4,6 @@ global using Masa.BuildingBlocks.Data; global using Microsoft.EntityFrameworkCore; global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Options; global using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure; global using System.Data.Common; -global using Microsoft.Extensions.Options; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/MasaDbContextOptionsBuilderExtensions.cs index 8a1521a3a..84c4eb556 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/MasaDbContextOptionsBuilderExtensions.cs @@ -23,28 +23,58 @@ public static MasaDbContextOptionsBuilder UseSqlServer( public static MasaDbContextOptionsBuilder UseSqlServer( this MasaDbContextOptionsBuilder builder, string connectionString, - Action? sqlServerOptionsAction = null) + Action? sqlServerOptionsAction) + => builder.UseSqlServerCore(connectionString, false, sqlServerOptionsAction); + + public static MasaDbContextOptionsBuilder UseTestSqlServer( + this MasaDbContextOptionsBuilder builder, + string connectionString, + Action? sqlServerOptionsAction) + => builder.UseSqlServerCore(connectionString, true, sqlServerOptionsAction); + + private static MasaDbContextOptionsBuilder UseSqlServerCore( + this MasaDbContextOptionsBuilder builder, + string connectionString, + bool isTest, + Action? sqlServerOptionsAction) { - builder.UseSqlServerCore(connectionString); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseSqlServer(connectionString, sqlServerOptionsAction); - return builder; + return builder.UseSqlServerCore(connectionString, isTest); } public static MasaDbContextOptionsBuilder UseSqlServer( this MasaDbContextOptionsBuilder builder, DbConnection connection, Action? sqlServerOptionsAction = null) + => builder.UseSqlServerCore(connection, false, sqlServerOptionsAction); + + public static MasaDbContextOptionsBuilder UseTestSqlServer( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + Action? sqlServerOptionsAction = null) + => builder.UseSqlServerCore(connection, true, sqlServerOptionsAction); + + private static MasaDbContextOptionsBuilder UseSqlServerCore( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + bool isTest, + Action? sqlServerOptionsAction = null) { - builder.UseSqlServerCore(connection.ConnectionString); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseSqlServer(connection, sqlServerOptionsAction); - return builder; + return builder.UseSqlServerCore(connection.ConnectionString, isTest); } - private static MasaDbContextOptionsBuilder UseSqlServerCore(this MasaDbContextOptionsBuilder builder, string connectionString) + private static MasaDbContextOptionsBuilder UseSqlServerCore( + this MasaDbContextOptionsBuilder builder, + string connectionString, + bool isTest = false) { var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + if (!isTest && dbConnectionOptions.ConnectionStrings.ContainsKey(name)) + throw new ArgumentException($"The [{builder.DbContextType.Name}] Database Connection String already exists"); + dbConnectionOptions.TryAddConnectionString(name, connectionString); return builder; } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/_Imports.cs index 267a343b6..4bc00c11b 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/_Imports.cs @@ -5,5 +5,5 @@ global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.Infrastructure; global using Microsoft.Extensions.DependencyInjection; -global using System.Data.Common; global using Microsoft.Extensions.Options; +global using System.Data.Common; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/MasaDbContextOptionsBuilderExtensions.cs index 65e449027..09f838c5b 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/MasaDbContextOptionsBuilderExtensions.cs @@ -24,27 +24,57 @@ public static MasaDbContextOptionsBuilder UseSqlite( this MasaDbContextOptionsBuilder builder, string connectionString, Action? sqliteOptionsAction = null) + => builder.UseSqliteCore(connectionString, false, sqliteOptionsAction); + + public static MasaDbContextOptionsBuilder UseTestSqlite( + this MasaDbContextOptionsBuilder builder, + string connectionString, + Action? sqliteOptionsAction = null) + => builder.UseSqliteCore(connectionString, true, sqliteOptionsAction); + + private static MasaDbContextOptionsBuilder UseSqliteCore( + this MasaDbContextOptionsBuilder builder, + string connectionString, + bool isTest, + Action? sqliteOptionsAction) { - builder.UseSqliteCore(connectionString); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseSqlite(connectionString, sqliteOptionsAction); - return builder; + return builder.UseSqliteCore(connectionString, isTest); } public static MasaDbContextOptionsBuilder UseSqlite( this MasaDbContextOptionsBuilder builder, DbConnection connection, Action? sqliteOptionsAction = null) + => builder.UseSqliteCore(connection, false, sqliteOptionsAction); + + public static MasaDbContextOptionsBuilder UseTestSqlite( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + Action? sqliteOptionsAction = null) + => builder.UseSqliteCore(connection, true, sqliteOptionsAction); + + private static MasaDbContextOptionsBuilder UseSqliteCore( + this MasaDbContextOptionsBuilder builder, + DbConnection connection, + bool isTest, + Action? sqliteOptionsAction = null) { - builder.UseSqliteCore(connection.ConnectionString); builder.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseSqlite(connection, sqliteOptionsAction); - return builder; + return builder.UseSqliteCore(connection.ConnectionString, isTest); } - private static MasaDbContextOptionsBuilder UseSqliteCore(this MasaDbContextOptionsBuilder builder, string connectionString) + private static MasaDbContextOptionsBuilder UseSqliteCore( + this MasaDbContextOptionsBuilder builder, + string connectionString, + bool isTest = false) { var dbConnectionOptions = builder.ServiceProvider.GetRequiredService>().CurrentValue; var name = ConnectionStringNameAttribute.GetConnStringName(builder.DbContextType); + if (!isTest && dbConnectionOptions.ConnectionStrings.ContainsKey(name)) + throw new ArgumentException($"The [{builder.DbContextType.Name}] Database Connection String already exists"); + dbConnectionOptions.TryAddConnectionString(name, connectionString); return builder; } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/_Imports.cs index 267a343b6..4bc00c11b 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/_Imports.cs @@ -5,5 +5,5 @@ global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.Infrastructure; global using Microsoft.Extensions.DependencyInjection; -global using System.Data.Common; global using Microsoft.Extensions.Options; +global using System.Data.Common; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/DefaultConnectionStringProvider.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/DefaultConnectionStringProvider.cs index 4ff366d62..d351e6dce 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/DefaultConnectionStringProvider.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/DefaultConnectionStringProvider.cs @@ -1,3 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + namespace Masa.Contrib.Data.EntityFrameworkCore; public class DefaultConnectionStringProvider : IConnectionStringProvider diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder.cs index 42c3cca74..99dc3c4fb 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder.cs @@ -1,17 +1,17 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + namespace Masa.Contrib.Data.EntityFrameworkCore; public abstract class EFDbContextOptionsBuilder { public readonly DbContextOptionsBuilder DbContextOptionsBuilder; - public IServiceProvider ServiceProvider { get; } - internal bool EnableSoftDelete { get; private set; } - protected EFDbContextOptionsBuilder(IServiceProvider serviceProvider, DbContextOptions options, bool enableSoftDelete) + protected EFDbContextOptionsBuilder(DbContextOptions options, bool enableSoftDelete) { DbContextOptionsBuilder = new DbContextOptionsBuilder(options); - ServiceProvider = serviceProvider; EnableSoftDelete = enableSoftDelete; } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder`.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder`.cs index 4dc06bd75..ab650aa58 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder`.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/EFDbContextOptionsBuilder`.cs @@ -1,10 +1,13 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + namespace Masa.Contrib.Data.EntityFrameworkCore; public class EFDbContextOptionsBuilder : EFDbContextOptionsBuilder where TDbContext : MasaDbContext, IMasaDbContext { - public EFDbContextOptionsBuilder(IServiceProvider serviceProvider) - : base(serviceProvider, new DbContextOptions(), false) + public EFDbContextOptionsBuilder() + : base(new DbContextOptions(), false) { } } diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/ISaveChangesFilter.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/ISaveChangesFilter.cs index f0e6380b4..ac9e73fc4 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/ISaveChangesFilter.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Filters/ISaveChangesFilter.cs @@ -1,3 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + namespace Masa.Contrib.Data.EntityFrameworkCore.Filters; public interface ISaveChangesFilter diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/IModelCreatingProvider.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/IModelCreatingProvider.cs index b7e07c17f..087a33ab1 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/IModelCreatingProvider.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/IModelCreatingProvider.cs @@ -1,4 +1,7 @@ -namespace Masa.Contrib.Data.EntityFrameworkCore; +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore; public interface IModelCreatingProvider { diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Contrib.Data.EntityFrameworkCore.csproj b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Contrib.Data.EntityFrameworkCore.csproj index ca24e104f..da99ba079 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Contrib.Data.EntityFrameworkCore.csproj +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/Masa.Contrib.Data.EntityFrameworkCore.csproj @@ -18,8 +18,4 @@ - - - - diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContext.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContext.cs index b20af47e8..8fae11b58 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContext.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContext.cs @@ -1,3 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + namespace Masa.Contrib.Data.EntityFrameworkCore; public abstract class MasaDbContext : DbContext, IMasaDbContext diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions.cs index f6560a3fa..3794d591b 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions.cs @@ -1,3 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + namespace Masa.Contrib.Data.EntityFrameworkCore; public abstract class MasaDbContextOptions : DbContextOptions diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder.cs index 98670b70d..c886014cb 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. namespace Masa.Contrib.Data.EntityFrameworkCore; diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions`.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions`.cs index a19a074b2..4d2c7c61e 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions`.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/MasaDbContextOptions`.cs @@ -1,3 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + namespace Masa.Contrib.Data.EntityFrameworkCore; public class MasaDbContextOptions : MasaDbContextOptions @@ -17,7 +20,6 @@ public MasaDbContextOptions( /// public override IEnumerable ModelCreatingProviders => _modelCreatingProviders ??= ServiceProvider.GetServices(); - private IEnumerable? _saveChangesFilters; /// diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.md index bc2f5ea70..b462e4894 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.md @@ -16,7 +16,7 @@ Using MasaDbContext ``` C# builder.Services.AddMasaDbContext(optionsBuilder => { - optionsBuilder.UseSoftDelete();//enable soft delete + optionsBuilder.UseFilter();//enable filtering optionsBuilder.DbContextOptionsBuilder.UseSqlServer("server=localhost;uid=sa;pwd=P@ssw0rd;database=identity"); }); ``` diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.zh-CN.md index d93d777cd..00fd800be 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.zh-CN.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/README.zh-CN.md @@ -6,6 +6,7 @@ ```c# Install-Package Masa.Contrib.Data.EntityFrameworkCore +Install-Package Masa.Contrib.Data.Contracts.EF Install-Package Microsoft.EntityFrameworkCore.SqlServer//这里以SqlServer举例 ``` @@ -16,7 +17,7 @@ Install-Package Microsoft.EntityFrameworkCore.SqlServer//这里以SqlServer举 ``` C# builder.Services.AddMasaDbContext(optionsBuilder => { - optionsBuilder.UseSoftDelete();//启用软删除 + optionsBuilder.UseFilter();//启用过滤 optionsBuilder.DbContextOptionsBuilder.UseSqlServer("server=localhost;uid=sa;pwd=P@ssw0rd;database=identity"); }); ``` diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/ServiceCollectionExtensions.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/ServiceCollectionExtensions.cs index 10fa218d5..d2d7b7bd5 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/ServiceCollectionExtensions.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/ServiceCollectionExtensions.cs @@ -1,3 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + namespace Masa.Contrib.Data.EntityFrameworkCore; public static class ServiceCollectionExtensions @@ -59,7 +62,7 @@ private static MasaDbContextOptions CreateMasaDbContex Action? optionsBuilder) where TDbContextImplementation : MasaDbContext, IMasaDbContext { - var efDbContextOptionsBuilder = new EFDbContextOptionsBuilder(serviceProvider); + var efDbContextOptionsBuilder = new EFDbContextOptionsBuilder(); optionsBuilder?.Invoke(serviceProvider, efDbContextOptionsBuilder); return CreateMasaDbContextOptions( diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/_Imports.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/_Imports.cs index 9e59f746f..dee832c0a 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/_Imports.cs @@ -1,3 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Data; global using Masa.BuildingBlocks.Data.Contracts.DataFiltering; diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/Internal/Const.cs b/src/Data/Masa.Contrib.Data.UoW.EF/Internal/Const.cs index a835594ff..7c0b9d177 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/Internal/Const.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/Internal/Const.cs @@ -1,4 +1,4 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. namespace Masa.Contrib.Data.UoW.EF.Internal; diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs b/src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs index a25dd87b0..360624a90 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs @@ -1,20 +1,17 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. -global using Masa.BuildingBlocks.Configuration; +global using Masa.BuildingBlocks.Data; global using Masa.BuildingBlocks.Data.UoW; global using Masa.BuildingBlocks.Dispatcher.Events; +global using Masa.Contrib.Data.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.Storage; -global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.DependencyInjection.Extensions; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; global using System.Data.Common; global using System.Text.Json.Serialization; -global using EntityState = Masa.BuildingBlocks.Data.UoW.EntityState; global using DbContextOptions = Masa.BuildingBlocks.Data.Options.MasaDbContextConfigurationOptions; -global using Masa.Contrib.Data.UoW.EF.Internal; -global using Masa.BuildingBlocks.Data; -global using Masa.Contrib.Data.EntityFrameworkCore; +global using EntityState = Masa.BuildingBlocks.Data.UoW.EntityState; diff --git a/src/Isolation/Masa.Contrib.Isolation.UoW.EF/README.md b/src/Isolation/Masa.Contrib.Isolation.UoW.EF/README.md index 1b51a1331..b00debb19 100644 --- a/src/Isolation/Masa.Contrib.Isolation.UoW.EF/README.md +++ b/src/Isolation/Masa.Contrib.Isolation.UoW.EF/README.md @@ -6,6 +6,7 @@ Example: ```C# Install-Package Masa.Contrib.Isolation.UoW.EF +Install-Package Masa.Contrib.Data.Contracts.EF Install-Package Masa.Contrib.Isolation.MultiEnvironment // Environmental isolation Quote on demand Install-Package Masa.Contrib.Isolation.MultiTenant // Multi-tenant isolation On-demand reference Install-Package Masa.Utils.Data.EntityFrameworkCore.SqlServer @@ -15,21 +16,21 @@ Install-Package Masa.Utils.Data.EntityFrameworkCore.SqlServer ``` appsettings.json { "ConnectionStrings": { - "DefaultConnection": "server=localhost;uid=sa;pwd=P@ssw0rd;database=identity;", - "Isolations": [ - { - "TenantId": "*",// match all tenants - "Environment": "development", - "ConnectionString": "server=localhost,1672;uid=sa;pwd=P@ssw0rd;database=identity;", - "Score": 99 // When multiple environments are matched according to the conditions, the highest one is selected as the link address of the current DbContext according to the descending order of scores. The default Score is 100. - }, - { - "TenantId": "00000000-0000-0000-0000-000000000002", - "Environment": "development", - "ConnectionString": "server=localhost,1674;uid=sa;pwd=P@ssw0rd;database=identity;" - } - ] - } + "DefaultConnection": "server=localhost;uid=sa;pwd=P@ssw0rd;database=identity;" + }, + "IsolationConnectionStrings": [ + { + "TenantId": "*",//match all tenants + "Environment": "development", + "ConnectionString": "server=localhost,1434;uid=sa;pwd=P@ssw0rd;database=identity;", + "Score": 99 //When multiple environments are matched according to the conditions, the highest one is selected as the link address of the current DbContext according to the descending order of scores. The default Score is 100. + }, + { + "TenantId": "00000000-0000-0000-0000-000000000002", + "Environment": "development", + "ConnectionString": "server=localhost,1435;uid=sa;pwd=P@ssw0rd;database=identity;" + } + ] } ``` @@ -46,7 +47,7 @@ builder.Services.AddEventBus(eventBusBuilder => { eventBusBuilder.UseIsolationUoW( isolationBuilder => isolationBuilder.UseMultiEnvironment().UseMultiTenant(),// Select usage environment or tenant isolation as needed - dbOptions => dbOptions.UseSqlServer()); + dbOptions => dbOptions.UseFilter().UseSqlServer()); }); ``` diff --git a/src/Isolation/Masa.Contrib.Isolation.UoW.EF/README.zh-CN.md b/src/Isolation/Masa.Contrib.Isolation.UoW.EF/README.zh-CN.md index d699472bf..d6e79f64b 100644 --- a/src/Isolation/Masa.Contrib.Isolation.UoW.EF/README.zh-CN.md +++ b/src/Isolation/Masa.Contrib.Isolation.UoW.EF/README.zh-CN.md @@ -6,6 +6,7 @@ ```C# Install-Package Masa.Contrib.Isolation.UoW.EF +Install-Package Masa.Contrib.Data.Contracts.EF Install-Package Masa.Contrib.Isolation.MultiEnvironment // 环境隔离 按需引用 Install-Package Masa.Contrib.Isolation.MultiTenant // 多租户隔离 按需引用 Install-Package Masa.Utils.Data.EntityFrameworkCore.SqlServer @@ -15,21 +16,21 @@ Install-Package Masa.Utils.Data.EntityFrameworkCore.SqlServer ``` appsettings.json { "ConnectionStrings": { - "DefaultConnection": "server=localhost;uid=sa;pwd=P@ssw0rd;database=identity;", - "Isolations": [ - { - "TenantId": "*",//匹配所有租户 - "Environment": "development", - "ConnectionString": "server=localhost,1672;uid=sa;pwd=P@ssw0rd;database=identity;", - "Score": 99 //当根据条件匹配到多个环境时,根据分值降序选择其中最高的作为当前DbContext的链接地址,Score默认为100 - }, - { - "TenantId": "00000000-0000-0000-0000-000000000002", - "Environment": "development", - "ConnectionString": "server=localhost,1674;uid=sa;pwd=P@ssw0rd;database=identity;" - } - ] - } + "DefaultConnection": "server=localhost;uid=sa;pwd=P@ssw0rd;database=identity;" + }, + "IsolationConnectionStrings": [ + { + "TenantId": "*",//匹配所有租户 + "Environment": "development", + "ConnectionString": "server=localhost,1434;uid=sa;pwd=P@ssw0rd;database=identity;", + "Score": 99 //当根据条件匹配到多个环境时,根据分值降序选择其中最高的作为当前DbContext的链接地址,Score默认为100 + }, + { + "TenantId": "00000000-0000-0000-0000-000000000002", + "Environment": "development", + "ConnectionString": "server=localhost,1435;uid=sa;pwd=P@ssw0rd;database=identity;" + } + ] } ``` @@ -46,7 +47,7 @@ builder.Services.AddEventBus(eventBusBuilder => { eventBusBuilder.UseIsolationUoW( isolationBuilder => isolationBuilder.UseMultiEnvironment().UseMultiTenant(),// 按需选择使用环境或者租户隔离 - dbOptions => dbOptions.UseSqlServer()); + dbOptions => dbOptions.UseFilter().UseSqlServer()); }); ``` From 39e68ecac29acc727f404bcab639d7c0f4abbef3 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 9 May 2022 17:04:48 +0800 Subject: [PATCH 04/10] test(EntityFramework): Refactor EntityFramework UnitTest --- .../DataFilterTest.cs | 47 +++++ ...asa.Contrib.Data.Contracts.EF.Tests.csproj | 3 +- .../_Imports.cs | 5 + .../CustomizeDbContext.cs | 18 ++ .../DbContextTest.cs | 193 ++++++++++++++++++ .../DefaultConnectionStringProviderTest.cs | 44 ++++ .../Internal/PaginatedOptions.cs | 11 + .../Internal/Repository.cs | 35 ++++ ...trib.Data.EntityFrameworkCore.Tests.csproj | 28 +++ .../Models/Address.cs | 11 + .../Models/Hobby.cs | 18 ++ .../Models/Student.cs | 19 ++ .../TestBase.cs | 34 +++ .../_Imports.cs | 14 ++ .../TestBase.cs | 2 +- .../TestUnitOfWork.cs | 86 +++++--- .../_Imports.cs | 2 +- .../BaseRepositoryTest.cs | 2 +- ...trib.Ddd.Domain.Repository.EF.Tests.csproj | 1 - .../RepositoryTest.cs | 4 +- .../IntegrationEventLogServiceTest.cs | 6 +- .../TestIsolation.cs | 2 +- test/Masa.Contrib.Isolation.Tests/_Imports.cs | 7 +- .../TestIsolation.cs | 14 +- .../appsettings.json | 30 +-- .../EdgeDriverTest.cs | 2 +- ....Contrib.Isolation.UoW.EF.Web.Tests.csproj | 1 + .../_Imports.cs | 1 + .../appsettings.json | 30 +-- 29 files changed, 592 insertions(+), 78 deletions(-) create mode 100644 test/Masa.Contrib.Data.Contracts.EF.Tests/DataFilterTest.cs create mode 100644 test/Masa.Contrib.Data.EntityFrameworkCore.Tests/CustomizeDbContext.cs create mode 100644 test/Masa.Contrib.Data.EntityFrameworkCore.Tests/DbContextTest.cs create mode 100644 test/Masa.Contrib.Data.EntityFrameworkCore.Tests/DefaultConnectionStringProviderTest.cs create mode 100644 test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Internal/PaginatedOptions.cs create mode 100644 test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Internal/Repository.cs create mode 100644 test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Masa.Contrib.Data.EntityFrameworkCore.Tests.csproj create mode 100644 test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Models/Address.cs create mode 100644 test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Models/Hobby.cs create mode 100644 test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Models/Student.cs create mode 100644 test/Masa.Contrib.Data.EntityFrameworkCore.Tests/TestBase.cs create mode 100644 test/Masa.Contrib.Data.EntityFrameworkCore.Tests/_Imports.cs diff --git a/test/Masa.Contrib.Data.Contracts.EF.Tests/DataFilterTest.cs b/test/Masa.Contrib.Data.Contracts.EF.Tests/DataFilterTest.cs new file mode 100644 index 000000000..afc0310fe --- /dev/null +++ b/test/Masa.Contrib.Data.Contracts.EF.Tests/DataFilterTest.cs @@ -0,0 +1,47 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.Contracts.EF.Tests; + +[TestClass] +public class DataFilterTest +{ + private IServiceCollection _services; + private IDataFilter _dataFilter; + + [TestInitialize] + public void Initialize() + { + _services = new ServiceCollection(); + _services.AddSingleton(); + _services.AddSingleton(typeof(DataFilter<>)); + _dataFilter = new DataFilter(_services.BuildServiceProvider()); + } + + [TestMethod] + public void TestDataFilterReturnTrue() + { + Assert.IsTrue(_dataFilter.IsEnabled()); + + using (_dataFilter.Disable()) + { + Assert.IsFalse(_dataFilter.IsEnabled()); + } + + Assert.IsTrue(_dataFilter.IsEnabled()); + } + + [TestMethod] + public void TestDataFilterReturnFalse() + { + _dataFilter.Disable(); + Assert.IsFalse(_dataFilter.IsEnabled()); + + using (_dataFilter.Enable()) + { + Assert.IsTrue(_dataFilter.IsEnabled()); + } + + Assert.IsFalse(_dataFilter.IsEnabled()); + } +} diff --git a/test/Masa.Contrib.Data.Contracts.EF.Tests/Masa.Contrib.Data.Contracts.EF.Tests.csproj b/test/Masa.Contrib.Data.Contracts.EF.Tests/Masa.Contrib.Data.Contracts.EF.Tests.csproj index 9c9838ff4..7627e5fd8 100644 --- a/test/Masa.Contrib.Data.Contracts.EF.Tests/Masa.Contrib.Data.Contracts.EF.Tests.csproj +++ b/test/Masa.Contrib.Data.Contracts.EF.Tests/Masa.Contrib.Data.Contracts.EF.Tests.csproj @@ -20,11 +20,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + diff --git a/test/Masa.Contrib.Data.Contracts.EF.Tests/_Imports.cs b/test/Masa.Contrib.Data.Contracts.EF.Tests/_Imports.cs index 2b37cc14c..05c2ff359 100644 --- a/test/Masa.Contrib.Data.Contracts.EF.Tests/_Imports.cs +++ b/test/Masa.Contrib.Data.Contracts.EF.Tests/_Imports.cs @@ -1,2 +1,7 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Data.Contracts.DataFiltering; +global using Masa.Contrib.Data.Contracts.EF.DataFiltering; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/CustomizeDbContext.cs b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/CustomizeDbContext.cs new file mode 100644 index 000000000..5f8997920 --- /dev/null +++ b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/CustomizeDbContext.cs @@ -0,0 +1,18 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Tests; + +public class CustomizeDbContext : MasaDbContext +{ + public CustomizeDbContext(MasaDbContextOptions options) : base(options) + { + } + + protected override void OnModelCreatingExecuting(ModelBuilder modelBuilder) + { + modelBuilder.Entity(); + modelBuilder.Entity().OwnsOne(x => x.Address); + modelBuilder.Entity().OwnsMany(t => t.Hobbies); + } +} diff --git a/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/DbContextTest.cs b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/DbContextTest.cs new file mode 100644 index 000000000..30fd9d841 --- /dev/null +++ b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/DbContextTest.cs @@ -0,0 +1,193 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Tests; + +[TestClass] +public class DbContextTest : TestBase +{ + [TestMethod] + public async Task TestAddAsync() + { + await using var dbContext = CreateDbContext(true, out _); + await dbContext.Set().AddAsync(new Student() + { + Id = 1, + Name = "Jim", + Age = 18, + Address = new Address() + { + City = "ShangHai", + Street = "PuDong", + }, + Hobbies = new List() + { + new() + { + Name = "Sing", + Description = "loves singing" + }, + new() + { + Name = "Game", + Description = "mobile game" + } + } + }); + await dbContext.SaveChangesAsync(); + Assert.IsTrue(await dbContext.Set().CountAsync() == 1); + } + + [TestMethod] + public async Task TestSoftDeleteAsync() + { + Services.Configure(options => + { + options.ConnectionStrings = new ConnectionStrings() + { + DefaultConnection = $"data source=soft-delete-db-{Guid.NewGuid()}" + }; + }); + await using var dbContext = CreateDbContext(true, out IServiceProvider serviceProvider, false); + var student = new Student() + { + Id = 1, + Name = "Jim", + Age = 18, + Address = new Address() + { + City = "ShangHai", + Street = "PuDong", + }, + Hobbies = new List() + { + new() + { + Name = "Sing", + Description = "loves singing" + }, + new() + { + Name = "Game", + Description = "mobile game" + } + } + }; + await dbContext.Set().AddAsync(student); + await dbContext.SaveChangesAsync(); + Assert.IsTrue(await dbContext.Set().CountAsync() == 1); + + student = await dbContext.Set().Include(s => s.Address).Include(s => s.Hobbies).FirstAsync(); + dbContext.Set().Remove(student); + await dbContext.SaveChangesAsync(); + + Assert.IsTrue(await dbContext.Set().CountAsync() == 0); + + var dataFilter = serviceProvider.GetRequiredService(); + using (dataFilter.Disable()) + { + Assert.IsTrue(await dbContext.Set().CountAsync() == 1); + + student = (await dbContext.Set().Include(s => s.Address).FirstOrDefaultAsync())!; + Assert.IsTrue(student.Id == 1); + Assert.IsTrue(student.Name == "Jim"); + Assert.IsTrue(student.Age == 18); + Assert.IsTrue(student.IsDeleted); + Assert.IsTrue(student.Address.City == "ShangHai"); + Assert.IsTrue(student.Address.Street == "PuDong"); + + Assert.IsTrue(student.Hobbies.Count == 2); + Assert.IsTrue(student.Hobbies.Any(h => h.Name == "Sing")); + Assert.IsTrue(student.Hobbies.Any(h => h.Name == "Game")); + } + } + + [TestMethod] + public async Task TestDisabledSoftDelete() + { + Services.AddMasaDbContext(options + => options.UseTestFilter().UseTestSqlite($"data source=disabled-soft-delete-db-{Guid.NewGuid()}")); + var serviceProvider = Services.BuildServiceProvider(); + var dbContext = serviceProvider.GetRequiredService(); + await dbContext.Database.EnsureCreatedAsync(); + var student = new Student + { + Id = 1, + Name = "Jim", + Age = 18, + Address = new Address() + { + City = "ShangHai", + Street = "PuDong", + } + }; + await dbContext.Set().AddAsync(student); + await dbContext.SaveChangesAsync(); + Assert.IsTrue(await dbContext.Set().CountAsync() == 1); + + dbContext.Set().Remove(student); + await dbContext.SaveChangesAsync(); + + Assert.IsTrue(await dbContext.Set().CountAsync() == 0); + + var dataFilter = serviceProvider.GetRequiredService(); + using (dataFilter.Disable()) + { + var count = await dbContext.Set().IgnoreQueryFilters().CountAsync(); + Assert.IsTrue(count == 1); + } + } + + [TestMethod] + public async Task TestGetPaginatedListAsyncReturnCountEqualResultCount() + { + Services.Configure(options => + { + options.ConnectionStrings = new ConnectionStrings() + { + DefaultConnection = $"data source=soft-delete-db-{Guid.NewGuid()}" + }; + }); + await using var dbContext = CreateDbContext(true, out IServiceProvider serviceProvider); + var students = new List() + { + new() + { + Id = 1, + Name = "Jim", + Age = 18, + Address = new Address() + { + City = "ShangHai", + Street = "PuDong", + } + }, + new() + { + Id = 2, + Name = "Tom", + Age = 20, + Address = new Address() + { + City = "ShangHai", + Street = "PuDong", + } + } + }; + await dbContext.Set().AddRangeAsync(students); + await dbContext.SaveChangesAsync(); + Assert.IsTrue(await dbContext.Set().CountAsync() == 2); + + var student = await dbContext.Set().FirstAsync(); + dbContext.Set().Remove(student); + await dbContext.SaveChangesAsync(); + + var result = await new Repository(dbContext).GetPaginatedListAsync(new PaginatedOptions() + { + Page = 1, + PageSize = 10 + }); + + Assert.IsTrue(result.Result.Count == result.Total); + } +} diff --git a/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/DefaultConnectionStringProviderTest.cs b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/DefaultConnectionStringProviderTest.cs new file mode 100644 index 000000000..b14e73e0e --- /dev/null +++ b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/DefaultConnectionStringProviderTest.cs @@ -0,0 +1,44 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Tests; + +[TestClass] +public class DefaultConnectionStringProviderTest +{ + [TestMethod] + public async Task TestGetConnectionStringAsyncReturnTest1() + { + IServiceCollection services = new ServiceCollection(); + services.Configure(options => + { + options.ConnectionStrings = new ConnectionStrings() + { + DefaultConnection = "Test1" + }; + }); + var serviceProvider = services.BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>(); + var defaultConnectionStringProvider = new DefaultConnectionStringProvider(options); + var connectionString = await defaultConnectionStringProvider.GetConnectionStringAsync(); + Assert.AreEqual("Test1", connectionString); + } + + [TestMethod] + public async Task TestGetConnectionStringAsyncAndNameIsEmptyReturnTest1() + { + IServiceCollection services = new ServiceCollection(); + services.Configure(options => + { + options.ConnectionStrings = new ConnectionStrings() + { + DefaultConnection = "Test1" + }; + }); + var serviceProvider = services.BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>(); + var defaultConnectionStringProvider = new DefaultConnectionStringProvider(options); + var connectionString = await defaultConnectionStringProvider.GetConnectionStringAsync(string.Empty); + Assert.AreEqual("Test1", connectionString); + } +} diff --git a/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Internal/PaginatedOptions.cs b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Internal/PaginatedOptions.cs new file mode 100644 index 000000000..14a21d266 --- /dev/null +++ b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Internal/PaginatedOptions.cs @@ -0,0 +1,11 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Tests.Internal; + +internal class PaginatedOptions +{ + public int Page { get; set; } + + public int PageSize { get; set; } +} diff --git a/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Internal/Repository.cs b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Internal/Repository.cs new file mode 100644 index 000000000..82bde9172 --- /dev/null +++ b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Internal/Repository.cs @@ -0,0 +1,35 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Tests.Internal; + +internal class Repository +{ + private readonly CustomizeDbContext _testDbContext; + + public Repository(CustomizeDbContext testDbContext) => _testDbContext = testDbContext; + + public Task> GetPaginatedListAsync(int skip, int take, CancellationToken cancellationToken = default) + => _testDbContext.Set().Skip(skip).Take(take).ToListAsync(cancellationToken); + + public virtual async Task> GetPaginatedListAsync(PaginatedOptions options, CancellationToken cancellationToken = default) + { + var result = await GetPaginatedListAsync( + (options.Page - 1) * options.PageSize, + options.PageSize <= 0 ? int.MaxValue : options.PageSize, + cancellationToken + ); + + var total = await GetCountAsync(cancellationToken); + + return new BasePaginatedList() + { + Total = total, + Result = result, + TotalPages = (int)Math.Ceiling(total / (decimal)options.PageSize) + }; + } + + public async Task GetCountAsync(CancellationToken cancellationToken = default) + => await _testDbContext.Set().LongCountAsync(cancellationToken); +} diff --git a/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Masa.Contrib.Data.EntityFrameworkCore.Tests.csproj b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Masa.Contrib.Data.EntityFrameworkCore.Tests.csproj new file mode 100644 index 000000000..70bbf7ce0 --- /dev/null +++ b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Masa.Contrib.Data.EntityFrameworkCore.Tests.csproj @@ -0,0 +1,28 @@ + + + + net6.0 + enable + false + enable + + + + + + + + + + + + + + + + + + + + + diff --git a/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Models/Address.cs b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Models/Address.cs new file mode 100644 index 000000000..2909884f3 --- /dev/null +++ b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Models/Address.cs @@ -0,0 +1,11 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Tests.Models; + +public class Address +{ + public string City { get; set; } = default!; + + public string Street { get; set; } = default!; +} diff --git a/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Models/Hobby.cs b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Models/Hobby.cs new file mode 100644 index 000000000..366e9a9b9 --- /dev/null +++ b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Models/Hobby.cs @@ -0,0 +1,18 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Tests.Models; + +public class Hobby +{ + public Guid Id { get; set; } + + public string Name { get; set; } = default!; + + public string Description { get; set; } = default!; + + public Hobby() + { + Id = Guid.NewGuid(); + } +} diff --git a/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Models/Student.cs b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Models/Student.cs new file mode 100644 index 000000000..9850f1531 --- /dev/null +++ b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/Models/Student.cs @@ -0,0 +1,19 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Tests.Models; + +public class Student : ISoftDelete +{ + public int Id { get; set; } + + public string Name { get; set; } = default!; + + public int Age { get; set; } + + public bool IsDeleted { get; private set; } = default!; + + public Address Address { get; set; } = default!; + + public List Hobbies { get; set; } = default!; +} diff --git a/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/TestBase.cs b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/TestBase.cs new file mode 100644 index 000000000..d25be19df --- /dev/null +++ b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/TestBase.cs @@ -0,0 +1,34 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Data.EntityFrameworkCore.Tests; + +public class TestBase +{ + protected IServiceCollection Services; + + [TestInitialize] + public void Initialize() + { + Services = new ServiceCollection(); + } + + protected CustomizeDbContext CreateDbContext(bool enableSoftDelete, out IServiceProvider serviceProvider, + bool initConnectionString = true) + { + Services.AddMasaDbContext(options => + { + if (enableSoftDelete) + options.UseTestFilter(); + + if (initConnectionString) + options.UseTestSqlite($"data source=test-{Guid.NewGuid()}"); + else + options.UseSqlite(); + }); + serviceProvider = Services.BuildServiceProvider(); + var dbContext = serviceProvider.GetRequiredService(); + dbContext.Database.EnsureCreated(); + return dbContext; + } +} diff --git a/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/_Imports.cs b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/_Imports.cs new file mode 100644 index 000000000..f2c8afcbc --- /dev/null +++ b/test/Masa.Contrib.Data.EntityFrameworkCore.Tests/_Imports.cs @@ -0,0 +1,14 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +global using Masa.BuildingBlocks.Data; +global using Masa.BuildingBlocks.Data.Contracts.DataFiltering; +global using Masa.BuildingBlocks.Data.Contracts.Paginated; +global using Masa.Contrib.Data.Contracts.EF; +global using Masa.Contrib.Data.EntityFrameworkCore.Tests.Internal; +global using Masa.Contrib.Data.EntityFrameworkCore.Tests.Models; +global using Microsoft.EntityFrameworkCore; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Options; +global using Microsoft.VisualStudio.TestTools.UnitTesting; +global using Masa.Contrib.Data.EntityFrameworkCore.Sqlite; diff --git a/test/Masa.Contrib.Data.UoW.EF.Tests/TestBase.cs b/test/Masa.Contrib.Data.UoW.EF.Tests/TestBase.cs index dc0872534..8b06e74be 100644 --- a/test/Masa.Contrib.Data.UoW.EF.Tests/TestBase.cs +++ b/test/Masa.Contrib.Data.UoW.EF.Tests/TestBase.cs @@ -3,7 +3,7 @@ namespace Masa.Contrib.Data.UoW.EF.Tests; -public class TestBase : IDisposable +public class TestBase { protected readonly string _connectionString = "DataSource=:memory:"; protected readonly SqliteConnection Connection; diff --git a/test/Masa.Contrib.Data.UoW.EF.Tests/TestUnitOfWork.cs b/test/Masa.Contrib.Data.UoW.EF.Tests/TestUnitOfWork.cs index 4026488a8..259c054f6 100644 --- a/test/Masa.Contrib.Data.UoW.EF.Tests/TestUnitOfWork.cs +++ b/test/Masa.Contrib.Data.UoW.EF.Tests/TestUnitOfWork.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +using Microsoft.Extensions.Options; + namespace Masa.Contrib.Data.UoW.EF.Tests; [TestClass] @@ -25,7 +27,7 @@ public void TestAddUoWAndNullServices() [TestMethod] public void TestAddUoWAndUseSqlLite() { - _options.Object.UseUoW(options => options.UseSqlite(_connectionString)); + _options.Object.UseUoW(options => options.UseTestSqlite(_connectionString)); var serviceProvider = _options.Object.Services.BuildServiceProvider(); Assert.IsNotNull(serviceProvider.GetRequiredService()); } @@ -34,8 +36,8 @@ public void TestAddUoWAndUseSqlLite() public void TestAddMultUoW() { _options.Object - .UseUoW(options => options.UseSqlite(_connectionString)) - .UseUoW(options => options.UseSqlite(_connectionString)); + .UseUoW(options => options.UseTestSqlite(_connectionString)) + .UseUoW(options => options.UseTestSqlite(_connectionString)); var serviceProvider = _options.Object.Services.BuildServiceProvider(); Assert.IsTrue(serviceProvider.GetServices().Count() == 1); @@ -51,7 +53,7 @@ public void TestTransaction() [TestMethod] public async Task TestUseTranscationAsync() { - _options.Object.UseUoW(options => options.UseSqlite(Connection)); + _options.Object.UseUoW(options => options.UseTestSqlite(Connection)); var serviceProvider = _options.Object.Services.BuildServiceProvider(); var dbContext = serviceProvider.GetRequiredService(); await dbContext.Database.EnsureCreatedAsync(); @@ -72,7 +74,7 @@ public async Task TestUseTranscationAsync() [TestMethod] public async Task TestNotUseTranscationAsync() { - _options.Object.UseUoW(options => options.UseSqlite(Connection)); + _options.Object.UseUoW(options => options.UseTestSqlite(Connection)); var serviceProvider = _options.Object.Services.BuildServiceProvider(); var dbContext = serviceProvider.GetRequiredService(); await dbContext.Database.EnsureCreatedAsync(); @@ -90,7 +92,7 @@ public async Task TestNotUseTranscationAsync() [TestMethod] public async Task TestNotTransactionCommitAsync() { - _options.Object.UseUoW(options => options.UseSqlite(_connectionString)); + _options.Object.UseUoW(options => options.UseTestSqlite(_connectionString)); var serviceProvider = _options.Object.Services.BuildServiceProvider(); var dbContext = serviceProvider.GetRequiredService(); await dbContext.Database.EnsureCreatedAsync(); @@ -101,7 +103,7 @@ public async Task TestNotTransactionCommitAsync() [TestMethod] public async Task TestCommitAsync() { - _options.Object.UseUoW(options => options.UseSqlite(Connection)); + _options.Object.UseUoW(options => options.UseTestSqlite(Connection)); var serviceProvider = _options.Object.Services.BuildServiceProvider(); var dbContext = serviceProvider.GetRequiredService(); await dbContext.Database.EnsureCreatedAsync(); @@ -121,7 +123,7 @@ public async Task TestCommitAsync() [TestMethod] public async Task TestOpenRollbackAsync() { - _options.Object.UseUoW(options => options.UseSqlite(Connection)); + _options.Object.UseUoW(options => options.UseTestSqlite(Connection)); var serviceProvider = _options.Object.Services.BuildServiceProvider(); var dbContext = serviceProvider.GetRequiredService(); await dbContext.Database.EnsureCreatedAsync(); @@ -138,7 +140,7 @@ public async Task TestOpenRollbackAsync() public async Task TestAddLoggerAndOpenRollbackAsync() { _options.Object.Services.AddLogging(); - _options.Object.UseUoW(options => options.UseSqlite(Connection)); + _options.Object.UseUoW(options => options.UseTestSqlite(Connection)); var serviceProvider = _options.Object.Services.BuildServiceProvider(); var dbContext = serviceProvider.GetRequiredService(); await dbContext.Database.EnsureCreatedAsync(); @@ -156,7 +158,7 @@ public void TestDataConnectionString() { IConfiguration configuration = new ConfigurationManager(); _options.Object.Services.AddSingleton(_ => configuration); - _options.Object.UseUoW(options => options.UseSqlite(Connection)); + _options.Object.UseUoW(options => options.UseTestSqlite(Connection)); var serviceProvider = _options.Object.Services.BuildServiceProvider(); var dataConnectionStringProvider = serviceProvider.GetRequiredService(); Assert.IsTrue(dataConnectionStringProvider.DbContextOptionsList.Count == 1 && @@ -166,7 +168,7 @@ public void TestDataConnectionString() [TestMethod] public void TestUnitOfWorkManager() { - _options.Object.UseUoW(options => options.UseSqlite(Connection)); + _options.Object.UseUoW(options => options.UseTestSqlite(Connection)); var serviceProvider = _options.Object.Services.BuildServiceProvider(); var unitOfWorkManager = serviceProvider.GetRequiredService(); var unitOfWork = serviceProvider.GetRequiredService(); @@ -189,11 +191,13 @@ public void TestUnitOfWorkManager() public async Task TestUnitOfWorkAccessorAsync() { var services = new ServiceCollection(); - var configurationRoot = new ConfigurationBuilder() - .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile("appsettings.json", true, true) - .Build(); - services.AddSingleton(configurationRoot); + services.Configure(options => + { + options.ConnectionStrings = new ConnectionStrings() + { + DefaultConnection = _connectionString + }; + }); _options.Setup(option => option.Services).Returns(services).Verifiable(); _options.Object.UseUoW(options => options.UseSqlite()); var serviceProvider = _options.Object.Services.BuildServiceProvider(); @@ -204,14 +208,14 @@ public async Task TestUnitOfWorkAccessorAsync() Assert.IsTrue(!unitOfWork.TransactionHasBegun); unitOfWorkAccessor = serviceProvider.GetService(); Assert.IsTrue(unitOfWorkAccessor!.CurrentDbContextOptions != null && unitOfWorkAccessor.CurrentDbContextOptions.ConnectionString == - configurationRoot["ConnectionStrings:DefaultConnection"].ToString()); + _connectionString); var unitOfWorkManager = serviceProvider.GetRequiredService(); var unitOfWorkNew = unitOfWorkManager.CreateDbContext(false); var unitOfWorkAccessorNew = unitOfWorkNew.ServiceProvider.GetService(); Assert.IsTrue(unitOfWorkAccessorNew!.CurrentDbContextOptions != null && unitOfWorkAccessorNew.CurrentDbContextOptions.ConnectionString == - configurationRoot["ConnectionStrings:DefaultConnection"].ToString()); + _connectionString); var unitOfWorkNew2 = unitOfWorkManager.CreateDbContext(new MasaDbContextConfigurationOptions("test")); @@ -228,11 +232,13 @@ public async Task TestUnitOfWorkAccessorAsync() public void TestUnitOfWorkByEventBusBuilder() { var services = new ServiceCollection(); - var configurationRoot = new ConfigurationBuilder() - .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile("appsettings.json", true, true) - .Build(); - services.AddSingleton(configurationRoot); + services.Configure(options => + { + options.ConnectionStrings = new ConnectionStrings() + { + DefaultConnection = _connectionString + }; + }); Mock eventBuilder = new(); eventBuilder.Setup(builder => builder.Services).Returns(services).Verifiable(); eventBuilder.Object.UseUoW(options => options.UseSqlite()); @@ -258,7 +264,39 @@ public void TestUnitOfWorkAndAddMasaConfiguationReturnUnitOfWorkIsNotNull() Assert.IsNotNull(serviecProvider.GetService()); var customDbContext = serviecProvider.GetRequiredService(); - Assert.IsTrue(GetDataBaseConnectionString(customDbContext) == serviecProvider.GetRequiredService().GetConfiguration(SectionTypes.Local)["ConnectionStrings:DefaultConnection"]); + Assert.IsTrue(GetDataBaseConnectionString(customDbContext) == + serviecProvider.GetRequiredService().GetConfiguration(SectionTypes.Local)[ + "ConnectionStrings:DefaultConnection"]); + } + + [TestMethod] + public async Task TestGetConnectionStringAndCurrentDbContextOptionsAsyncReturnTest1() + { + Mock unitOfWorkAccessor = new(); + string connectionString = "Test1"; + unitOfWorkAccessor.Setup(accessor => accessor.CurrentDbContextOptions) + .Returns(new MasaDbContextConfigurationOptions(connectionString)); + var connectionStringProvider = new DefaultConnectionStringProvider(unitOfWorkAccessor.Object, null!); + Assert.IsTrue(await connectionStringProvider.GetConnectionStringAsync() == connectionString); + } + + [TestMethod] + public async Task TestGetConnectionStringAsyncReturnTest1() + { + Mock unitOfWorkAccessor = new(); + string connectionString = "Test1"; + IServiceCollection services = new ServiceCollection(); + services.Configure(options => + { + options.ConnectionStrings = new ConnectionStrings() + { + DefaultConnection = connectionString + }; + }); + var serviceProvider = services.BuildServiceProvider(); + var connectionStringProvider = new DefaultConnectionStringProvider(unitOfWorkAccessor.Object, + serviceProvider.GetRequiredService>()); + Assert.IsTrue(await connectionStringProvider.GetConnectionStringAsync() == connectionString); } private string GetDataBaseConnectionString(CustomDbContext dbContext) => dbContext.Database.GetConnectionString()!; diff --git a/test/Masa.Contrib.Data.UoW.EF.Tests/_Imports.cs b/test/Masa.Contrib.Data.UoW.EF.Tests/_Imports.cs index d068d67aa..f535daad0 100644 --- a/test/Masa.Contrib.Data.UoW.EF.Tests/_Imports.cs +++ b/test/Masa.Contrib.Data.UoW.EF.Tests/_Imports.cs @@ -3,6 +3,7 @@ global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Data; +global using Masa.BuildingBlocks.Data.Options; global using Masa.BuildingBlocks.Data.UoW; global using Masa.BuildingBlocks.Dispatcher.Events; global using Masa.Contrib.Configuration; @@ -18,4 +19,3 @@ global using Moq; global using System; global using System.Threading.Tasks; -global using Masa.BuildingBlocks.Data.Options; diff --git a/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/BaseRepositoryTest.cs b/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/BaseRepositoryTest.cs index 358baf7f7..742cbc573 100644 --- a/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/BaseRepositoryTest.cs +++ b/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/BaseRepositoryTest.cs @@ -88,7 +88,7 @@ public void TestEntityRepositoryShouldBeExist() { _dispatcherOptions.Setup(option => option.Assemblies).Returns(_assemblies).Verifiable(); _services.AddScoped(typeof(IUnitOfWork), _ => _uoW.Object); - _services.AddMasaDbContext(options => options.UseSqlite(Connection)); + _services.AddMasaDbContext(options => options.UseTestSqlite(Connection)); _dispatcherOptions.Object.UseRepository().UseRepository(); var serviceProvider = _services.BuildServiceProvider(); diff --git a/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/Masa.Contrib.Ddd.Domain.Repository.EF.Tests.csproj b/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/Masa.Contrib.Ddd.Domain.Repository.EF.Tests.csproj index df6b25bdb..3453d12ad 100644 --- a/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/Masa.Contrib.Ddd.Domain.Repository.EF.Tests.csproj +++ b/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/Masa.Contrib.Ddd.Domain.Repository.EF.Tests.csproj @@ -20,7 +20,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/RepositoryTest.cs b/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/RepositoryTest.cs index 8194742f8..d8fc76fc8 100644 --- a/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/RepositoryTest.cs +++ b/test/Masa.Contrib.Ddd.Domain.Repository.EF.Tests/RepositoryTest.cs @@ -29,7 +29,7 @@ public async Task InitializeAsync(Action? action) _dispatcherOptions.Setup(options => options.Services).Returns(() => _services); _dispatcherOptions.Setup(options => options.Assemblies).Returns(() => _assemblies); if (action == null) - _services.AddMasaDbContext(options => options.UseSqlite(Connection)); + _services.AddMasaDbContext(options => options.UseTestSqlite(Connection)); else action.Invoke(_services); @@ -389,7 +389,7 @@ public async Task TestDbTransactionAsync() public async Task TestServiceLifeAsync() { var services = new ServiceCollection(); - services.AddMasaDbContext(options => options.UseSqlite(Connection)); + services.AddMasaDbContext(options => options.UseTestSqlite(Connection)); var serviceProvider = services.BuildServiceProvider(); await using (var scope = serviceProvider.CreateAsyncScope()) diff --git a/test/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests/IntegrationEventLogServiceTest.cs b/test/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests/IntegrationEventLogServiceTest.cs index 782c7356e..71c610d92 100644 --- a/test/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests/IntegrationEventLogServiceTest.cs +++ b/test/Masa.Contrib.Dispatcher.IntegrationEvents.EventLogs.EF.Tests/IntegrationEventLogServiceTest.cs @@ -10,7 +10,7 @@ public class IntegrationEventLogServiceTest : TestBase public async Task TestNullDbTransactionAsync() { var services = new ServiceCollection(); - services.AddMasaDbContext(builder => builder.UseSqlite(ConnectionString)) + services.AddMasaDbContext(builder => builder.UseTestSqlite(ConnectionString)) .AddScoped(); IDispatcherOptions dispatcherOptions = CreateDispatcherOptions(services); dispatcherOptions.UseEventLog(); @@ -53,7 +53,7 @@ public async Task TestRetrieveEventLogsFailedToPublishAsync() { var dispatcherOptions = CreateDispatcherOptions(new ServiceCollection()); dispatcherOptions.UseEventLog(); - dispatcherOptions.Services.AddMasaDbContext(option => option.UseSqlite(Connection)); + dispatcherOptions.Services.AddMasaDbContext(option => option.UseTestSqlite(Connection)); dispatcherOptions.Services.AddScoped(); var serviceProvider = dispatcherOptions.Services.BuildServiceProvider(); await serviceProvider.GetRequiredService().Database.EnsureCreatedAsync(); @@ -279,7 +279,7 @@ public async Task TestMarkEventAsFailed2Async() var dispatcherOptions = CreateDispatcherOptions(new ServiceCollection()); dispatcherOptions.UseEventLog(); dispatcherOptions.Services.AddMasaDbContext(option => - option.UseSqlite(Connection)); + option.UseTestSqlite(Connection)); dispatcherOptions.Services.AddScoped(); Mock integrationEventBus = new(); var types = AppDomain.CurrentDomain.GetAssemblies() diff --git a/test/Masa.Contrib.Isolation.Tests/TestIsolation.cs b/test/Masa.Contrib.Isolation.Tests/TestIsolation.cs index e112f6d2d..a9061928c 100644 --- a/test/Masa.Contrib.Isolation.Tests/TestIsolation.cs +++ b/test/Masa.Contrib.Isolation.Tests/TestIsolation.cs @@ -144,7 +144,7 @@ public void TestUseIsolation8() => isolationBuilder.UseMultiTenant().UseMultiEnvironment()); var serviceProvider = services.BuildServiceProvider(); - Assert.IsTrue(services.Count(service => service.ServiceType == typeof(IIsolationMiddleware)) == 1); + Assert.IsTrue(services.Count(service => service.ServiceType == typeof(IIsolationMiddleware)) == 2); Assert.IsTrue(serviceProvider.GetServices().Count() == 1); Assert.IsTrue(serviceProvider.GetServices().Count() == 1); diff --git a/test/Masa.Contrib.Isolation.Tests/_Imports.cs b/test/Masa.Contrib.Isolation.Tests/_Imports.cs index d4f836802..8dc426a07 100644 --- a/test/Masa.Contrib.Isolation.Tests/_Imports.cs +++ b/test/Masa.Contrib.Isolation.Tests/_Imports.cs @@ -1,10 +1,12 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Masa.BuildingBlocks.Data; +global using Masa.BuildingBlocks.Data.Options; global using Masa.BuildingBlocks.Data.UoW; global using Masa.BuildingBlocks.Dispatcher.Events; -global using Masa.BuildingBlocks.Isolation; global using Masa.BuildingBlocks.Isolation.Environment; +global using Masa.BuildingBlocks.Isolation.Middleware; global using Masa.BuildingBlocks.Isolation.MultiTenant; global using Masa.BuildingBlocks.Isolation.Options; global using Masa.BuildingBlocks.Isolation.Parser; @@ -19,6 +21,3 @@ global using Moq; global using System; global using System.Linq; -global using Masa.BuildingBlocks.Data; -global using Masa.BuildingBlocks.Data.Options; -global using Masa.BuildingBlocks.Isolation.Middleware; diff --git a/test/Masa.Contrib.Isolation.UoW.EF.Tests/TestIsolation.cs b/test/Masa.Contrib.Isolation.UoW.EF.Tests/TestIsolation.cs index 1009da268..e4c8cd870 100644 --- a/test/Masa.Contrib.Isolation.UoW.EF.Tests/TestIsolation.cs +++ b/test/Masa.Contrib.Isolation.UoW.EF.Tests/TestIsolation.cs @@ -25,7 +25,7 @@ public void TestUseIsolationUoW() { eventBuilder.Object.UseIsolationUoW(_ => { - }, dbOptionBuilder => dbOptionBuilder.UseSqlite(_connectionString)); + }, dbOptionBuilder => dbOptionBuilder.UseTestSqlite(_connectionString)); }, "Tenant isolation and environment isolation use at least one"); } @@ -36,7 +36,7 @@ public void TestUseIsolationUoW2() eventBuilder.Setup(builder => builder.Services).Returns(_services).Verifiable(); Assert.ThrowsException(() => { - eventBuilder.Object.UseIsolationUoW(null!, dbOptionBuilder => dbOptionBuilder.UseSqlite(_connectionString)); + eventBuilder.Object.UseIsolationUoW(null!, dbOptionBuilder => dbOptionBuilder.UseTestSqlite(_connectionString)); }); } @@ -49,7 +49,7 @@ public void TestUseIsolationUoW3() { dispatcherOption.Object.UseIsolationUoW(_ => { - }, dbOptionBuilder => dbOptionBuilder.UseSqlite(_connectionString)); + }, dbOptionBuilder => dbOptionBuilder.UseTestSqlite(_connectionString)); }, "Tenant isolation and environment isolation use at least one"); } @@ -69,7 +69,7 @@ public void TestUseIsolationUoWByUseEnvironment() { Mock dispatcherOption = new(); dispatcherOption.Setup(builder => builder.Services).Returns(_services).Verifiable(); - dispatcherOption.Object.UseIsolationUoW(isolationBuilder => isolationBuilder.UseMultiEnvironment(), dbOptionBuilder => dbOptionBuilder.UseSqlite(_connectionString)); + dispatcherOption.Object.UseIsolationUoW(isolationBuilder => isolationBuilder.UseMultiEnvironment(), dbOptionBuilder => dbOptionBuilder.UseTestSqlite(_connectionString)); var serviceProvider = dispatcherOption.Object.Services.BuildServiceProvider(); Assert.IsNotNull(serviceProvider.GetService()); @@ -81,7 +81,7 @@ public void TestUseIsolationUoWByUseMultiEnvironment() { Mock dispatcherOption = new(); dispatcherOption.Setup(builder => builder.Services).Returns(_services).Verifiable(); - dispatcherOption.Object.UseIsolationUoW(isolationBuilder => isolationBuilder.UseMultiEnvironment().UseMultiEnvironment(), dbOptionBuilder => dbOptionBuilder.UseSqlite(_connectionString)); + dispatcherOption.Object.UseIsolationUoW(isolationBuilder => isolationBuilder.UseMultiEnvironment().UseMultiEnvironment(), dbOptionBuilder => dbOptionBuilder.UseTestSqlite(_connectionString)); var serviceProvider = dispatcherOption.Object.Services.BuildServiceProvider(); Assert.IsTrue(serviceProvider.GetServices().Count() == 1); @@ -93,7 +93,7 @@ public void TestUseIsolationUoWByUseTenant() { Mock dispatcherOption = new(); dispatcherOption.Setup(builder => builder.Services).Returns(_services).Verifiable(); - dispatcherOption.Object.UseIsolationUoW(isolationBuilder => isolationBuilder.UseMultiTenant(), dbOptionBuilder => dbOptionBuilder.UseSqlite(_connectionString)); + dispatcherOption.Object.UseIsolationUoW(isolationBuilder => isolationBuilder.UseMultiTenant(), dbOptionBuilder => dbOptionBuilder.UseTestSqlite(_connectionString)); var serviceProvider = dispatcherOption.Object.Services.BuildServiceProvider(); Assert.IsNotNull(serviceProvider.GetService()); @@ -105,7 +105,7 @@ public void TestUseIsolationUoWByUseMultiTenant() { Mock dispatcherOption = new(); dispatcherOption.Setup(builder => builder.Services).Returns(_services).Verifiable(); - dispatcherOption.Object.UseIsolationUoW(isolationBuilder => isolationBuilder.UseMultiTenant().UseMultiTenant(), dbOptionBuilder => dbOptionBuilder.UseSqlite(_connectionString)); + dispatcherOption.Object.UseIsolationUoW(isolationBuilder => isolationBuilder.UseMultiTenant().UseMultiTenant(), dbOptionBuilder => dbOptionBuilder.UseTestSqlite(_connectionString)); var serviceProvider = dispatcherOption.Object.Services.BuildServiceProvider(); Assert.IsTrue(serviceProvider.GetServices().Count() == 1); diff --git a/test/Masa.Contrib.Isolation.UoW.EF.Tests/appsettings.json b/test/Masa.Contrib.Isolation.UoW.EF.Tests/appsettings.json index d60224647..dbbc90933 100644 --- a/test/Masa.Contrib.Isolation.UoW.EF.Tests/appsettings.json +++ b/test/Masa.Contrib.Isolation.UoW.EF.Tests/appsettings.json @@ -1,18 +1,18 @@ { "ConnectionStrings": { - "DefaultConnection": "data source=test1", - "Isolations": [ - { - "TenantId": "*", - "Environment": "development", - "ConnectionString": "data source=test2", - "Score": 99 - }, - { - "TenantId": "00000000-0000-0000-0000-000000000002", - "Environment": "production", - "ConnectionString": "data source=test3" - } - ] - } + "DefaultConnection": "data source=test1" + }, + "IsolationConnectionStrings": [ + { + "TenantId": "*", + "Environment": "development", + "ConnectionString": "data source=test2", + "Score": 99 + }, + { + "TenantId": "00000000-0000-0000-0000-000000000002", + "Environment": "production", + "ConnectionString": "data source=test3" + } + ] } \ No newline at end of file diff --git a/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/EdgeDriverTest.cs b/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/EdgeDriverTest.cs index 8c96a6b11..1e4407e15 100644 --- a/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/EdgeDriverTest.cs +++ b/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/EdgeDriverTest.cs @@ -18,7 +18,7 @@ public void Initialize() _services = new ServiceCollection(); _services.AddSingleton(configurationRoot); _services.AddEventBus(eventBusBuilder => eventBusBuilder.UseIsolationUoW( - isolationBuilder => isolationBuilder.UseMultiTenant("tenant").UseMultiEnvironment("env"), dbOptions => dbOptions.UseSqlite())); + isolationBuilder => isolationBuilder.UseMultiTenant("tenant").UseMultiEnvironment("env"), dbOptions => dbOptions.UseFilter().UseSqlite())); System.Environment.SetEnvironmentVariable("env", "pro"); } diff --git a/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/Masa.Contrib.Isolation.UoW.EF.Web.Tests.csproj b/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/Masa.Contrib.Isolation.UoW.EF.Web.Tests.csproj index 368e33e1f..ca00f31a4 100644 --- a/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/Masa.Contrib.Isolation.UoW.EF.Web.Tests.csproj +++ b/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/Masa.Contrib.Isolation.UoW.EF.Web.Tests.csproj @@ -16,6 +16,7 @@ + diff --git a/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/_Imports.cs b/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/_Imports.cs index 5eb3faaca..0417473dd 100644 --- a/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/_Imports.cs +++ b/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/_Imports.cs @@ -5,6 +5,7 @@ global using Masa.BuildingBlocks.Dispatcher.Events; global using Masa.BuildingBlocks.Isolation; global using Masa.BuildingBlocks.Isolation.Environment; +global using Masa.Contrib.Data.Contracts.EF; global using Masa.Contrib.Data.EntityFrameworkCore; global using Masa.Contrib.Data.EntityFrameworkCore.Sqlite; global using Masa.Contrib.Dispatcher.Events; diff --git a/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/appsettings.json b/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/appsettings.json index 460845f83..478264b26 100644 --- a/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/appsettings.json +++ b/test/Masa.Contrib.Isolation.UoW.EF.Web.Tests/appsettings.json @@ -1,18 +1,18 @@ { "ConnectionStrings": { - "DefaultConnection": "data source=test1", - "Isolations": [ - { - "TenantId": "1", - "Environment": "dev", - "ConnectionString": "data source=test2", - "Score": 99 - }, - { - "TenantId": "2", - "Environment": "pro", - "ConnectionString": "data source=test3" - } - ] - } + "DefaultConnection": "data source=test1" + }, + "IsolationConnectionStrings": [ + { + "TenantId": "1", + "Environment": "dev", + "ConnectionString": "data source=test2", + "Score": 99 + }, + { + "TenantId": "2", + "Environment": "pro", + "ConnectionString": "data source=test3" + } + ] } \ No newline at end of file From 320fd9785d16c2487fc97d6300b08c8bf9f826ce Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 9 May 2022 17:06:22 +0800 Subject: [PATCH 05/10] chore: Change .editorconfig --- .editorconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.editorconfig b/.editorconfig index e0d8c1a2e..4246e89c9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -31,3 +31,13 @@ indent_size = 2 # JSON files [*.json] indent_size = 2 + +# Use Upper Case for constant fields +dotnet_naming_style.upper_case_style.capitalization = all_upper +dotnet_naming_style.upper_case_style.word_separator = _ +dotnet_naming_rule.constant_fields_should_be_upper_case.severity = warning +dotnet_naming_rule.constant_fields_should_be_upper_case.symbols = constant_fields +dotnet_naming_rule.constant_fields_should_be_upper_case.style = upper_case_style +dotnet_naming_symbols.constant_fields.applicable_kinds = field +dotnet_naming_symbols.constant_fields.applicable_accessibilities = * +dotnet_naming_symbols.constant_fields.required_modifiers = const \ No newline at end of file From 334b11a986418468bf729ab62f504784ca877e34 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 9 May 2022 17:22:34 +0800 Subject: [PATCH 06/10] chore: format code --- .../MasaDbContextOptionsBuilderExtensions.cs | 2 +- .../DefaultConnectionStringProvider.cs | 2 +- src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkAccessor.cs | 2 +- src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkManager.cs | 2 +- src/Isolation/Masa.Contrib.Isolation/_Imports.cs | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Data/Masa.Contrib.Data.Contracts.EF/MasaDbContextOptionsBuilderExtensions.cs b/src/Data/Masa.Contrib.Data.Contracts.EF/MasaDbContextOptionsBuilderExtensions.cs index 5b222256c..997e47aa7 100644 --- a/src/Data/Masa.Contrib.Data.Contracts.EF/MasaDbContextOptionsBuilderExtensions.cs +++ b/src/Data/Masa.Contrib.Data.Contracts.EF/MasaDbContextOptionsBuilderExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. namespace Masa.Contrib.Data.Contracts.EF; diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/DefaultConnectionStringProvider.cs b/src/Data/Masa.Contrib.Data.UoW.EF/DefaultConnectionStringProvider.cs index 7d45dc43b..9d2c5cef0 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/DefaultConnectionStringProvider.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/DefaultConnectionStringProvider.cs @@ -1,4 +1,4 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. namespace Masa.Contrib.Data.UoW.EF; diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkAccessor.cs b/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkAccessor.cs index e69401698..ba5fdd86c 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkAccessor.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkAccessor.cs @@ -1,4 +1,4 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. namespace Masa.Contrib.Data.UoW.EF; diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkManager.cs b/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkManager.cs index 1f0f3294d..a5e03dce9 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkManager.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkManager.cs @@ -1,4 +1,4 @@ -// Copyright (c) MASA Stack All rights reserved. +// Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. namespace Masa.Contrib.Data.UoW.EF; diff --git a/src/Isolation/Masa.Contrib.Isolation/_Imports.cs b/src/Isolation/Masa.Contrib.Isolation/_Imports.cs index 30a02286c..cb06356dd 100644 --- a/src/Isolation/Masa.Contrib.Isolation/_Imports.cs +++ b/src/Isolation/Masa.Contrib.Isolation/_Imports.cs @@ -2,6 +2,8 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. global using Masa.BuildingBlocks.Configuration; +global using Masa.BuildingBlocks.Data; +global using Masa.BuildingBlocks.Data.Options; global using Masa.BuildingBlocks.Data.UoW; global using Masa.BuildingBlocks.Dispatcher.Events; global using Masa.BuildingBlocks.Isolation; @@ -18,5 +20,3 @@ global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; global using System.Linq.Expressions; -global using Masa.BuildingBlocks.Data; -global using Masa.BuildingBlocks.Data.Options; From e00505b3584fbfc24bd1fa8d86652d897baf9d01 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 9 May 2022 17:27:03 +0800 Subject: [PATCH 07/10] docs(EntityFrameworkCore): Adjust filter documentation --- .../Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.md | 6 +++--- .../README.zh-CN.md | 6 +++--- .../README.md | 4 ++-- .../README.zh-CN.md | 4 ++-- .../Masa.Contrib.Data.EntityFrameworkCore.MySql/README.md | 4 ++-- .../README.zh-CN.md | 4 ++-- .../Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.md | 4 ++-- .../README.zh-CN.md | 4 ++-- .../README.md | 4 ++-- .../README.zh-CN.md | 4 ++-- .../README.md | 4 ++-- .../README.zh-CN.md | 4 ++-- .../README.md | 4 ++-- .../README.zh-CN.md | 4 ++-- .../Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.md | 4 ++-- .../README.zh-CN.md | 4 ++-- 16 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.md index 8c9c1eaab..de4021a5f 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.md @@ -23,12 +23,12 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.Cosmos 2. Using MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseCosmos()); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseCosmos()); ``` ##### Usage 2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseCosmos($"{accountEndpoint}",$"{accountKey}",$"{databaseName}")); -//builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseCosmos($"{connectionString}",$"{databaseName}")); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseCosmos($"{accountEndpoint}",$"{accountKey}",$"{databaseName}")); +//builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseCosmos($"{connectionString}",$"{databaseName}")); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.zh-CN.md index b1b62c4f6..fba9c83bf 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.zh-CN.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Cosmos/README.zh-CN.md @@ -23,12 +23,12 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.Cosmos 2. 使用MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseCosmos()); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseCosmos()); ``` #### 用法2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseCosmos($"{accountEndpoint}",$"{accountKey}",$"{databaseName}")); -//builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseCosmos($"{connectionString}",$"{databaseName}")); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseCosmos($"{accountEndpoint}",$"{accountKey}",$"{databaseName}")); +//builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseCosmos($"{connectionString}",$"{databaseName}")); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.md index f9c193b86..b4293b730 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.md @@ -23,11 +23,11 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.InMemory 2. Using MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseInMemoryDatabase()); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseInMemoryDatabase()); ``` ##### Usage 2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseInMemoryDatabase("identity")); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseInMemoryDatabase("identity")); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.zh-CN.md index 449197f2c..e28c40a0e 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.zh-CN.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.InMemory/README.zh-CN.md @@ -23,11 +23,11 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.InMemory 2. 使用MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseInMemoryDatabase()); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseInMemoryDatabase()); ``` #### 用法2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseInMemoryDatabase("identity")); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseInMemoryDatabase("identity")); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.md index 3a24ada64..967a2674f 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.md @@ -23,11 +23,11 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.MySql 2. Using MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySQL()); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseMySQL()); ``` ##### Usage 2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySQL("Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;")); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseMySQL("Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;")); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.zh-CN.md index 6e4b4a057..f19a31586 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.zh-CN.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.MySql/README.zh-CN.md @@ -23,11 +23,11 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.MySql 2. 使用MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySQL()); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseMySQL()); ``` #### 用法2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySQL("Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;")); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseMySQL("Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;")); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.md index 8967cc155..97f1a32b5 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.md @@ -23,11 +23,11 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.Oracle 2. Using MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseOracle()); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseOracle()); ``` ##### Usage 2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseOracle("Data Source=MyOracleDB;Integrated Security=yes;")); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseOracle("Data Source=MyOracleDB;Integrated Security=yes;")); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.zh-CN.md index 4ebf69c70..fd3328d07 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.zh-CN.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Oracle/README.zh-CN.md @@ -23,11 +23,11 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.Oracle 2. 使用MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseOracle()); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseOracle()); ``` #### 用法2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseOracle("Data Source=MyOracleDB;Integrated Security=yes;")); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseOracle("Data Source=MyOracleDB;Integrated Security=yes;")); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.md index 09b00ab60..5d170c32a 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.md @@ -23,11 +23,11 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql 2. Using MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySql(Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.28-mysql"))); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseMySql(Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.28-mysql"))); ``` ##### Usage 2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySql("Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;", Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.28-mysql"))); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseMySql("Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;", Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.28-mysql"))); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.zh-CN.md index 0b2c8b376..9113e1bb1 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.zh-CN.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql/README.zh-CN.md @@ -23,11 +23,11 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql 2. 使用MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySql(Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.28-mysql"))); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseMySql(Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.28-mysql"))); ``` #### 用法2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseMySql("Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;", Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.28-mysql"))); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseMySql("Server=localhost;Database=identity;Uid=myUsername;Pwd=P@ssw0rd;", Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.28-mysql"))); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.md index 5f14aef33..88af3796e 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.md @@ -23,11 +23,11 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.PostgreSql 2. Using MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseNpgsql()); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseNpgsql()); ``` ##### Usage 2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseNpgsql("Host=myserver;Username=sa;Password=P@ssw0rd;Database=identity")); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseNpgsql("Host=myserver;Username=sa;Password=P@ssw0rd;Database=identity")); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.zh-CN.md index 41aa6ad39..99af59623 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.zh-CN.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.PostgreSql/README.zh-CN.md @@ -23,11 +23,11 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.PostgreSql 2. 使用MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseNpgsql()); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseNpgsql()); ``` #### 用法2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseNpgsql("Host=myserver;Username=sa;Password=P@ssw0rd;Database=identity")); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseNpgsql("Host=myserver;Username=sa;Password=P@ssw0rd;Database=identity")); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.md index 68d1af184..3bb2223f2 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.md @@ -23,11 +23,11 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.SqlServer 2. Using MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlServer()); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseSqlServer()); ``` ##### Usage 2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlServer("server=localhost;uid=sa;pwd=P@ssw0rd;database=identity")); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseSqlServer("server=localhost;uid=sa;pwd=P@ssw0rd;database=identity")); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.zh-CN.md index 9df34a017..baca04f2f 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.zh-CN.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.SqlServer/README.zh-CN.md @@ -23,11 +23,11 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.SqlServer 2. 使用MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlServer()); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseSqlServer()); ``` #### 用法2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlServer("server=localhost;uid=sa;pwd=P@ssw0rd;database=identity")); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseSqlServer("server=localhost;uid=sa;pwd=P@ssw0rd;database=identity")); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.md index 5275a936f..f67058740 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.md @@ -23,11 +23,11 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.Sqlite 2. Using MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlite()); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseSqlite()); ``` ##### Usage 2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlite("Data Source=c:\mydb.db;Version=3;Password=P@ssw0rd;")); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseSqlite("Data Source=c:\mydb.db;Version=3;Password=P@ssw0rd;")); ``` \ No newline at end of file diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.zh-CN.md b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.zh-CN.md index 372101b81..bcef8183c 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.zh-CN.md +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore.Sqlite/README.zh-CN.md @@ -23,11 +23,11 @@ Install-Package Masa.Contrib.Data.EntityFrameworkCore.Sqlite 2. 使用MasaDbContext ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlite()); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseSqlite()); ``` #### 用法2: ``` C# -builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseSoftDelete().UseSqlite("Data Source=c:\mydb.db;Version=3;Password=P@ssw0rd;")); +builder.Services.AddMasaDbContext(optionsBuilder => optionsBuilder.UseFilter().UseSqlite("Data Source=c:\mydb.db;Version=3;Password=P@ssw0rd;")); ``` \ No newline at end of file From dd6817d65372e31c72669fd5ef6a464354fafcc2 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Mon, 9 May 2022 17:57:21 +0800 Subject: [PATCH 08/10] chore: Adjust Global Using --- .../Masa.Contrib.Data.UoW.EF/DefaultConnectionStringProvider.cs | 2 +- src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkAccessor.cs | 2 +- src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkManager.cs | 2 +- src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/DefaultConnectionStringProvider.cs b/src/Data/Masa.Contrib.Data.UoW.EF/DefaultConnectionStringProvider.cs index 9d2c5cef0..b6d21ebc7 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/DefaultConnectionStringProvider.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/DefaultConnectionStringProvider.cs @@ -31,7 +31,7 @@ public string GetConnectionString(string name = ConnectionStrings.DEFAULT_CONNEC if (string.IsNullOrEmpty(connectionString)) _logger?.LogError("Failed to get database connection string, please check whether the configuration of IOptionsSnapshot is abnormal"); - _unitOfWorkAccessor.CurrentDbContextOptions = new DbContextOptions(connectionString); + _unitOfWorkAccessor.CurrentDbContextOptions = new MasaDbContextConfigurationOptions(connectionString); return connectionString; } } diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkAccessor.cs b/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkAccessor.cs index ba5fdd86c..9f25b6e13 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkAccessor.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkAccessor.cs @@ -5,5 +5,5 @@ namespace Masa.Contrib.Data.UoW.EF; public class UnitOfWorkAccessor : IUnitOfWorkAccessor { - public DbContextOptions? CurrentDbContextOptions { get; set; } + public MasaDbContextConfigurationOptions? CurrentDbContextOptions { get; set; } } diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkManager.cs b/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkManager.cs index a5e03dce9..39b9a2ad0 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkManager.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/UnitOfWorkManager.cs @@ -24,7 +24,7 @@ public IUnitOfWork CreateDbContext(bool lazyLoading = true) return scope.ServiceProvider.GetRequiredService(); } - public IUnitOfWork CreateDbContext(DbContextOptions options) + public IUnitOfWork CreateDbContext(MasaDbContextConfigurationOptions options) { ArgumentNullException.ThrowIfNull(options, nameof(options)); if (string.IsNullOrEmpty(options.ConnectionString)) diff --git a/src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs b/src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs index 360624a90..bfc1f48c3 100644 --- a/src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs +++ b/src/Data/Masa.Contrib.Data.UoW.EF/_Imports.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. global using Masa.BuildingBlocks.Data; +global using Masa.BuildingBlocks.Data.Options; global using Masa.BuildingBlocks.Data.UoW; global using Masa.BuildingBlocks.Dispatcher.Events; global using Masa.Contrib.Data.EntityFrameworkCore; @@ -13,5 +14,4 @@ global using Microsoft.Extensions.Options; global using System.Data.Common; global using System.Text.Json.Serialization; -global using DbContextOptions = Masa.BuildingBlocks.Data.Options.MasaDbContextConfigurationOptions; global using EntityState = Masa.BuildingBlocks.Data.UoW.EntityState; From 3f187cb4a52856e24a225db22f89510c1b9bcea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=AC=E9=9B=A8=E5=A3=B0?= Date: Mon, 9 May 2022 21:15:55 +0800 Subject: [PATCH 09/10] Update .editorconfig --- .editorconfig | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.editorconfig b/.editorconfig index 4246e89c9..4edb0cdd2 100644 --- a/.editorconfig +++ b/.editorconfig @@ -20,6 +20,16 @@ indent_size = 4 insert_final_newline = true charset = utf-8 +# Use Upper Case for constant fields +dotnet_naming_style.upper_case_style.capitalization = all_upper +dotnet_naming_style.upper_case_style.word_separator = _ +dotnet_naming_rule.constant_fields_should_be_upper_case.severity = warning +dotnet_naming_rule.constant_fields_should_be_upper_case.symbols = constant_fields +dotnet_naming_rule.constant_fields_should_be_upper_case.style = upper_case_style +dotnet_naming_symbols.constant_fields.applicable_kinds = field +dotnet_naming_symbols.constant_fields.applicable_accessibilities = * +dotnet_naming_symbols.constant_fields.required_modifiers = const + # Xml project files [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] indent_size = 2 @@ -31,13 +41,3 @@ indent_size = 2 # JSON files [*.json] indent_size = 2 - -# Use Upper Case for constant fields -dotnet_naming_style.upper_case_style.capitalization = all_upper -dotnet_naming_style.upper_case_style.word_separator = _ -dotnet_naming_rule.constant_fields_should_be_upper_case.severity = warning -dotnet_naming_rule.constant_fields_should_be_upper_case.symbols = constant_fields -dotnet_naming_rule.constant_fields_should_be_upper_case.style = upper_case_style -dotnet_naming_symbols.constant_fields.applicable_kinds = field -dotnet_naming_symbols.constant_fields.applicable_accessibilities = * -dotnet_naming_symbols.constant_fields.required_modifiers = const \ No newline at end of file From 6af8c7c6bb3414f8fb91b603f2f42aaa05844945 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Tue, 10 May 2022 16:48:51 +0800 Subject: [PATCH 10/10] chore: Add method annotation --- .../IModelCreatingProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/IModelCreatingProvider.cs b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/IModelCreatingProvider.cs index 087a33ab1..0fa3ebcb5 100644 --- a/src/Data/Masa.Contrib.Data.EntityFrameworkCore/IModelCreatingProvider.cs +++ b/src/Data/Masa.Contrib.Data.EntityFrameworkCore/IModelCreatingProvider.cs @@ -6,7 +6,7 @@ namespace Masa.Contrib.Data.EntityFrameworkCore; public interface IModelCreatingProvider { /// - /// + /// For building DbContext models and their mappings /// /// void Configure(ModelBuilder modelBuilder);