Preface
Masa
Provides the basis for EntityFramework
Data integration for , It also provides the functions of data filtering and soft deletion , Now we will introduce how to use it ?
MasaDbContext introduction
- install .Net 6.0
newly build ASP.NET Core Empty item
Assignment.MasaEntityFramework
, And installMasa.Contrib.Data.EntityFrameworkCore
、Swashbuckle.AspNetCore
、Microsoft.EntityFrameworkCore.InMemory
、Microsoft.EntityFrameworkCore.Tools
dotnet add package Masa.Contrib.Data.EntityFrameworkCore --version 0.4.0-rc.4 dotnet add package Swashbuckle.AspNetCore --version 6.2.3 dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 6.0.5 dotnet add package Microsoft.EntityFrameworkCore.Tools --version 6.0.5
install
Swashbuckle.AspNetCore
For the convenience of passingSwagger
To operate the service
installMicrosoft.EntityFrameworkCore.InMemory
It's for convenience , So use an in memory database , If you need to use other databases , Please install the corresponding package by yourself
installMicrosoft.EntityFrameworkCore.Tools
To use CodeFirst Create databaseThe new class
User
public class User { public int Id { get; set; } public string Name { get; set; } public uint Gender { get; set; } public DateTime BirthDay { get; set; } public DateTime CreationTime { get; set; } public User() { this.CreationTime = DateTime.Now; } }
New user context
UserDbContext.cs
public class UserDbContext : MasaDbContext { public DbSet<User> User { get; set; } public UserDbContext(MasaDbContextOptions options) : base(options) { } }
UserDbContext
Instead of inheritanceMasaDbContext
, And add a parameter constructor , Parameter type isMasaDbContextOptions
When there are multiple DbContext when , It needs to be inheritedMasaDbContext<TDbContext>
, The constructor parameter type is changed toMasaDbContext<TDbContext>
The new class
AddUserRequest
As a parameter for adding userspublic class AddUserRequest { public string Name { get; set; } public uint Gender { get; set; } public DateTime BirthDay { get; set; } }
The new class
HostExtensions
For migrating databases ( Use CodeFirst)public static class HostExtensions { public static void MigrateDbContext<TContext>( this IHost host, Action<TContext, IServiceProvider> seeder) where TContext : DbContext { using (var scope = host.Services.CreateScope()) { var services = scope.ServiceProvider; var context = services.GetRequiredService<TContext>(); context.Database.EnsureCreated(); seeder(context, services); } } }
modify
Program.cs
, newly addedSwagger
Supportbuilder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); app.UseSwagger(); app.UseSwaggerUI();
Unwanted
Swagger
Don't add , Use Swagger Just to test and invoke the service , UsePostman
Or something else Http Tools can also
modify
Program.cs
, Add user context ( a key )builder.Services.AddMasaDbContext<UserDbContext>(options => { options.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseInMemoryDatabase("test") });
modify
Program.cs
, Make the project support CodeFirstapp.MigrateDbContext<UserDbContext>((context, services) => { });
Unwanted CodeFirst, Code generation is not supported, and the database cannot be added
test
MasaDbContext
, modifyProgram.cs
app.MapPost("/add", (UserDbContext dbContext, [FromBody] AddUserRequest request) => { dbContext.Set<User>().Add(new User() { Name = request.Name, Gender = request.Gender, BirthDay = request.BirthDay }); dbContext.SaveChanges(); }); app.MapGet("/list", (UserDbContext dbContext) => { return dbContext.Set<User>().ToList(); });
Run the project by yourself , perform
add
Then create a new user , After performinglist
Get more than one user data , Then proveMasaDbContext
Correct use
How to use soft delete
Choose
Assignment.MasaEntityFramework
And installMasa.Contrib.Data.Contracts.EF
dotnet add package Masa.Contrib.Data.Contracts.EF --version 0.4.0-rc.4
Modify the class
User
, And implementISoftDelete
, Change the code to :public class User : ISoftDelete// a key : Change to implementation ISoftDelete { public int Id { get; set; } public string Name { get; set; } public uint Gender { get; set; } public DateTime BirthDay { get; set; } public DateTime CreationTime { get; set; } public bool IsDeleted { get; private set; } public User() { this.CreationTime = DateTime.Now; } }
Increase implementation
ISoftDelete
, And forIsDeleted
Attribute addition set Support ( It can be private set;)modify
Program.cs
, And enable data filteringbuilder.Services.AddMasaDbContext<UserDbContext>(options => { options.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseInMemoryDatabase("test"); options.UseFilter();// Enable data filtering , Complete writing :options.UseFilter(filterOptions => filterOptions.EnableSoftDelete = true); });
Test whether the soft deletion is successful
modify
Program.cs
, Add delete methodapp.MapDelete("/delete", (UserDbContext dbContext, int id) => { var user = dbContext.Set<User>().First(u => u.Id == id); dbContext.Set<User>().Remove(user); dbContext.SaveChanges(); });
Last , First call add
Method after creating the user , Call later list
Method to get the list of all users , And take out any one id Information , Then call delete
Method to delete the user , Last call list
Method , View removed id Whether there is , To verify whether the soft deletion is effective .
How to temporarily disable soft deletion filtering
In the default query, the data marked with deleted tags will be filtered and no longer be queried , But there are also some scenarios that need to query all the data , At this point, you need to use data filtering IDataFilter
newly added
All
Method is used to query all data ( Contains data marked as deleted )app.MapGet("/all", (UserDbContext dbContext, [FromServices] IDataFilter dataFilter) => { // adopt DI Get IDataFilter, And call it Disable Method can be temporarily disabled ISoftDelete filter using (dataFilter.Disable<ISoftDelete>()) { return dbContext.Set<User>().ToList(); } });
Rerun the project , Repeat the steps of verifying soft deletion , Make sure to pass
list
Method cannot access dataThe reason for repeating the verify soft delete step is that this example uses an in memory database , After the project stops , All data will be cleared , Re execution is to ensure that the data exists , Only marked for deletion
perform
all
Method , Get all the data , see id Whether the corresponding user data exists
Get the database connection string from the configuration file
Selected items
Assignment.MasaEntityFramework
, And installMasa.Contrib.Data.EntityFrameworkCore.InMemory
dotnet add package Masa.Contrib.Data.EntityFrameworkCore.InMemory --version 0.4.0-rc.4
Install the corresponding database package as needed , Such as :
Masa.Contrib.Data.EntityFrameworkCore.SqlServer
(SqlServer)、Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql
(Pomelo Provided MySql)、Masa.Contrib.Data.EntityFrameworkCore.Oracle
(Oracle) etc.modify
Program.cs
, Adjust the configuration of adding user context to :builder.Services.AddMasaDbContext<UserDbContext>(options => options.UseInMemoryDatabase().UseFilter());
modify
appsettings.json
, Add user database connection string :{ "ConnectionStrings": { "DefaultConnection": "test"// Replace with the specified database connection string } }
modify
Program.cs
, newly addeddatabase
Method , Verify that the current database istest
app.MapGet("/database", (UserDbContext dbContext) => { var field = typeof(MasaDbContext).GetField("Options", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic)!; var masaDbContextOptions = field.GetValue(dbContext) as MasaDbContextOptions; foreach (var dbContextOptionsExtension in masaDbContextOptions!.Extensions) { if (dbContextOptionsExtension is InMemoryOptionsExtension memoryOptionsExtension) { return memoryOptionsExtension.StoreName; } } return ""; });
Last visit http://localhost:5002/database
, Verify whether the current database name is consistent with the modified database name
common problem
- How to change the default read configuration node ?
Modify user context
UserDbContext
And increaseConnectionStringName
characteristic :[ConnectionStringName("User")]// Custom node name public class UserDbContext : MasaDbContext { public DbSet<User> User { get; set; } public UserDbContext(MasaDbContextOptions options) : base(options) { } }
Modify the configuration
appsettings.json
{ "ConnectionStrings": { "User": "test"// Instead of from User The node reads the database connection string } }
- In addition to getting from the configuration file , Does it also support getting database connection strings from other places ?
There are currently two ways to change the database connection string .
Method 1: modify Program.cs
, And delete appsettings.json
Configuration of database connection string
modify
Program.cs
builder.Services.Configure<MasaDbConnectionOptions>(option => { option.ConnectionStrings = new ConnectionStrings(new List<KeyValuePair<string, string>>() { new("User", "test2")// Where the key is the node name , And ConnectionStringName Characteristic Name Keep the values consistent , If not specified ConnectionStringName, It should be DefaultConnection, The value is the database connection string }); });
modify
appsettings.json
To configure// "ConnectionStrings": { // "User": "test" // },
call
database
Method , Verify whether the current database istest2
Method 2: rewrite IConnectionStringProvider
and IDbConnectionStringProvider
And add to DI in
The new class
CustomizeConnectionStringProvider
public class CustomizeConnectionStringProvider : IConnectionStringProvider { public Task<string> GetConnectionStringAsync(string name = "DefaultConnection") => Task.FromResult (GetConnectionString(name)); public string GetConnectionString(string name = "DefaultConnection") => "test3"; }
The new class
CustomizeDbConnectionStringProvider
public class CustomizeDbConnectionStringProvider : IDbConnectionStringProvider { public List<MasaDbContextConfigurationOptions> DbContextOptionsList { get; } = new() { new MasaDbContextConfigurationOptions("test3") }; }
modify
Program.cs
builder.Services.AddSingleton<IConnectionStringProvider,CustomizeConnectionStringProvider>(); builder.Services.AddSingleton<IDbConnectionStringProvider,CustomizeDbConnectionStringProvider>();
call
database
Method , Verify whether the current database istest3
summary
This article mainly explains MasaDbContext
Basic usage and soft deletion 、 How to use data filtering , In the next article, we will explain MasaDbContext
How to realize soft deletion 、 Data filtered , And how to realize it when using the database without specifying the database link string mentioned in this article
Source code of this chapter
Assignment05
https://github.com/zhenlei520/MasaFramework.Practice
Open source address
MASA.BuildingBlocks:https://github.com/masastack/MASA.BuildingBlocks
MASA.Contrib:https://github.com/masastack/MASA.Contrib
MASA.Utils:https://github.com/masastack/MASA.Utils
MASA.EShop:https://github.com/masalabs/MASA.EShop
MASA.Blazor:https://github.com/BlazorComponent/MASA.Blazor
If you treat our MASA Framework Interested in , Whether it's code contribution 、 Use 、 carry Issue, Welcome to contact us