Skip to content

Commit a3873a9

Browse files
authored
fix: fix [issues-542](#542) (#543)
1 parent 6661e81 commit a3873a9

File tree

4 files changed

+80
-18
lines changed

4 files changed

+80
-18
lines changed

src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore/DefaultMasaDbContext.cs

+20-12
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,20 @@ internal void TryInitializeMasaDbContextOptions(MasaDbContextOptions? options)
7171

7272
try
7373
{
74-
base.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
74+
_ = base.ChangeTracker;
7575
}
7676
catch (InvalidOperationException ex)
7777
{
78-
var logger = Options!.ServiceProvider?.GetService(Options.ContextType) as ILogger;
79-
logger?.LogDebug("Error generating data context", ex);
80-
throw new InvalidOperationException(
81-
"No database provider has been configured for this DbContext. A provider can be configured by overriding the 'MasaDbContext.OnConfiguring' method or by using 'AddMasaDbContext' on the application service provider. If 'AddMasaDbContext' is used, then also ensure that your DbContext type accepts a 'MasaDbContextOptions<TContext>' object in its constructor and passes it to the base constructor for DbContext.");
78+
ILogger? logger = null;
79+
if (options != null)
80+
{
81+
var loggerType = typeof(ILogger<>).MakeGenericType(options.ContextType);
82+
logger = options.ServiceProvider?.GetService(loggerType) as ILogger;
83+
}
84+
85+
logger ??= MasaApp.GetService<ILogger<MasaDbContext>>();
86+
logger?.LogDebug(ex, "Error generating data context");
87+
throw new InvalidOperationException("No database provider has been configured for this DbContext. A provider can be configured by overriding the 'MasaDbContext.OnConfiguring' method or by using 'AddMasaDbContext' on the application service provider. If 'AddMasaDbContext' is used, then also ensure that your DbContext type accepts a 'MasaDbContextOptions<TContext>' object in its constructor and passes it to the base constructor for DbContext.");
8288
}
8389
}
8490

@@ -158,8 +164,8 @@ protected virtual void ConfigureGlobalFilters<TEntity>(ModelBuilder modelBuilder
158164
if (typeof(IMultiEnvironment).IsAssignableFrom(typeof(TEntity)) && EnvironmentContext != null)
159165
{
160166
Expression<Func<TEntity, bool>> envFilter = entity => !IsEnvironmentFilterEnabled ||
161-
EF.Property<string>(entity, nameof(IMultiEnvironment.Environment))
162-
.Equals(EnvironmentContext != null ? EnvironmentContext.CurrentEnvironment : default);
167+
EF.Property<string>(entity, nameof(IMultiEnvironment.Environment))
168+
.Equals(EnvironmentContext != null ? EnvironmentContext.CurrentEnvironment : default);
163169
expression = envFilter.And(expression != null, expression);
164170
}
165171

@@ -176,11 +182,12 @@ protected virtual void ConfigureGlobalFilters<TEntity>(ModelBuilder modelBuilder
176182
{
177183
string defaultTenantId = Guid.Empty.ToString();
178184
Expression<Func<TEntity, bool>> tenantFilter = entity => !IsTenantFilterEnabled ||
179-
(EF.Property<Guid>(entity, nameof(IMultiTenant<Guid>.TenantId)).ToString())
180-
.Equals(TenantContext.CurrentTenant != null ? TenantContext.CurrentTenant.Id : defaultTenantId);
185+
(EF.Property<Guid>(entity, nameof(IMultiTenant<Guid>.TenantId)).ToString())
186+
.Equals(TenantContext.CurrentTenant != null ? TenantContext.CurrentTenant.Id : defaultTenantId);
181187

182188
expression = tenantFilter.And(expression != null, expression);
183189
}
190+
184191
return expression;
185192
}
186193

@@ -294,7 +301,7 @@ public class DefaultMasaDbContext<TMultiTenantId> : DefaultMasaDbContext
294301
{
295302
protected override bool IsTenantFilterEnabled => DataFilter?.IsEnabled<IMultiTenant<TMultiTenantId>>() ?? false;
296303

297-
protected DefaultMasaDbContext()
304+
protected DefaultMasaDbContext() : base()
298305
{
299306
}
300307

@@ -310,11 +317,12 @@ public DefaultMasaDbContext(MasaDbContextOptions options) : base(options)
310317
{
311318
string defaultTenantId = default(TMultiTenantId)?.ToString() ?? string.Empty;
312319
Expression<Func<TEntity, bool>> tenantFilter = entity => !IsTenantFilterEnabled ||
313-
(EF.Property<TMultiTenantId>(entity, nameof(IMultiTenant<TMultiTenantId>.TenantId)).ToString() ?? string.Empty)
314-
.Equals(TenantContext.CurrentTenant != null ? TenantContext.CurrentTenant.Id : defaultTenantId);
320+
(EF.Property<TMultiTenantId>(entity, nameof(IMultiTenant<TMultiTenantId>.TenantId)).ToString() ?? string.Empty)
321+
.Equals(TenantContext.CurrentTenant != null ? TenantContext.CurrentTenant.Id : defaultTenantId);
315322

316323
expression = tenantFilter.And(expression != null, expression);
317324
}
325+
318326
return expression;
319327
}
320328
}

src/Contrib/Data/Orm/EFCore/Masa.Contrib.Data.EFCore/Extensions/ServiceCollectionExtensions.cs

+10-6
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ private static IServiceCollection AddCoreServices<TDbContextImplementation>(
4343
{
4444
parameters.Add(serviceProvider.GetService(parameter.ParameterType));
4545
}
46-
var dbContext = parameters.Count > 0 ?
47-
Activator.CreateInstance(typeof(TDbContextImplementation), parameters.ToArray()) as DefaultMasaDbContext :
48-
Activator.CreateInstance(typeof(TDbContextImplementation)) as DefaultMasaDbContext;
46+
47+
var dbContext = parameters.Count > 0
48+
? Activator.CreateInstance(typeof(TDbContextImplementation), parameters.ToArray()) as DefaultMasaDbContext
49+
: Activator.CreateInstance(typeof(TDbContextImplementation)) as DefaultMasaDbContext;
4950
MasaArgumentException.ThrowIfNull(dbContext);
5051

5152
dbContext.TryInitializeMasaDbContextOptions(serviceProvider.GetService<MasaDbContextOptions<TDbContextImplementation>>());
@@ -57,8 +58,12 @@ private static IServiceCollection AddCoreServices<TDbContextImplementation>(
5758
optionsBuilder?.Invoke(masaBuilder);
5859
return services.AddCoreServices<TDbContextImplementation>((serviceProvider, efDbContextOptionsBuilder) =>
5960
{
60-
efDbContextOptionsBuilder.DbContextOptionsBuilder.UseApplicationServiceProvider(serviceProvider);
61-
masaBuilder.Builder?.Invoke(serviceProvider, efDbContextOptionsBuilder.DbContextOptionsBuilder);
61+
if (masaBuilder.Builder != null)
62+
{
63+
efDbContextOptionsBuilder.DbContextOptionsBuilder.UseApplicationServiceProvider(serviceProvider);
64+
efDbContextOptionsBuilder.DbContextOptionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
65+
masaBuilder.Builder.Invoke(serviceProvider, efDbContextOptionsBuilder.DbContextOptionsBuilder);
66+
}
6267
}, masaBuilder.EnableSoftDelete, optionsLifetime);
6368
}
6469

@@ -180,7 +185,6 @@ private static IServiceCollection TryAddConfigure<TOptions>(
180185
#pragma warning disable S2094
181186
private sealed class MasaDbContextProvider<TDbContext>
182187
{
183-
184188
}
185189
#pragma warning restore S2094
186190
#pragma warning restore S2326

src/Contrib/Data/Orm/EFCore/Scenes/Masa.Contrib.Data.EFCore.Tests.Scenes.Isolation/CustomDbContext.cs

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class CustomDbContext2 : MasaDbContext
1818

1919
public CustomDbContext2(MasaDbContextOptions<CustomDbContext2> options) : base(options)
2020
{
21+
base.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTrackingWithIdentityResolution;
2122
}
2223
}
2324

@@ -29,6 +30,8 @@ protected override void OnConfiguring(MasaDbContextOptionsBuilder optionsBuilder
2930
{
3031
var connectionString = "data source=customDbContext3";
3132
optionsBuilder.UseSqlite(connectionString);
33+
34+
optionsBuilder.DbContextOptionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTrackingWithIdentityResolution);
3235
}
3336
}
3437

src/Contrib/Data/Orm/EFCore/Scenes/Masa.Contrib.Data.EFCore.Tests.Scenes.Isolation/MasaDbContextTest.cs

+47
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) MASA Stack All rights reserved.
22
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
33

4+
using Microsoft.Extensions.Logging;
5+
46
namespace Masa.Contrib.Data.EFCore.Tests.Scenes.Isolation;
57

68
[TestClass]
@@ -95,6 +97,50 @@ public async Task TestTenantIdByAddOrderAsync()
9597
Assert.AreEqual(2, orderAll.Count);
9698
}
9799

100+
[TestMethod]
101+
public void TestQueryTrackingBehaviorByDefault()
102+
{
103+
var services = new ServiceCollection();
104+
services.AddMasaDbContext<CustomDbContext>(dbContext =>
105+
{
106+
dbContext.UseInMemoryDatabase(Guid.NewGuid().ToString());
107+
dbContext.UseFilter();
108+
});
109+
var rootServiceProvider = services.BuildServiceProvider();
110+
111+
var dbContext = rootServiceProvider.GetRequiredService<CustomDbContext>();
112+
Assert.AreEqual(QueryTrackingBehavior.NoTracking, dbContext.ChangeTracker.QueryTrackingBehavior);
113+
}
114+
115+
[TestMethod]
116+
public void TestCustomQueryTrackingBehaviorByConstructor()
117+
{
118+
var services = new ServiceCollection();
119+
services.AddMasaDbContext<CustomDbContext2>(dbContext =>
120+
{
121+
dbContext.UseInMemoryDatabase(Guid.NewGuid().ToString());
122+
dbContext.UseFilter();
123+
});
124+
var rootServiceProvider = services.BuildServiceProvider();
125+
126+
var dbContext = rootServiceProvider.GetRequiredService<CustomDbContext2>();
127+
Assert.AreEqual(QueryTrackingBehavior.NoTrackingWithIdentityResolution, dbContext.ChangeTracker.QueryTrackingBehavior);
128+
}
129+
130+
[TestMethod]
131+
public void TestCustomQueryTrackingBehaviorByOnConfiguring()
132+
{
133+
var services = new ServiceCollection();
134+
services.AddMasaDbContext<CustomDbContext3>(dbContext =>
135+
{
136+
dbContext.UseFilter();
137+
});
138+
var rootServiceProvider = services.BuildServiceProvider();
139+
140+
var dbContext = rootServiceProvider.GetRequiredService<CustomDbContext3>();
141+
Assert.AreEqual(QueryTrackingBehavior.NoTrackingWithIdentityResolution, dbContext.ChangeTracker.QueryTrackingBehavior);
142+
}
143+
98144
[TestMethod]
99145
public async Task TestTenantIdByAddOrderAndNoConstructorAsync()
100146
{
@@ -135,6 +181,7 @@ public async Task TestTenantIdByAddOrderAndNoConstructorAsync()
135181
[TestMethod]
136182
public void TestAddMasaDbContextWhenNotUseDatabase()
137183
{
184+
_services.AddLogging(log => log.AddConsole());
138185
_services.AddMasaDbContext<CustomDbContext4>(builder => builder.UseFilter());
139186
var rootServiceProvider = _services.BuildServiceProvider();
140187

0 commit comments

Comments
 (0)