很抱歉,您提供的信息不完整,我无法直接给出答案。请您提供更具体的问题或信息,这样我才能更好地帮助您。

2026-03-30 15:151阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2095个文字,预计阅读时间需要9分钟。

很抱歉,您提供的信息不完整,我无法直接给出答案。请您提供更具体的问题或信息,这样我才能更好地帮助您。

前言:WebAPI是一种协议,用于允许网络应用程序(如浏览器)与网络服务器(如Web服务器)之间进行通信。它可以处理数据、访问数据库、处理图像和视频,以及执行其他高级功能。

前言

WebAPI是一种协议,用于允许网络应用程序(如浏览器)与网络服务器(如Web服务器)之间进行通信。它可以用于处理数据,访问数据库,处理图像和视频,以及进行其他高级功能。

本文涉及的知识量巨大主要有如下:

  • EFCore
  • Autofac
  • Serilog
  • Swagger
  • 非常多底层知识

一、使用控制台手搭webapi框架

1.配置文件

appsettings.Development.json

{ "Serilog": { "MinimumLevel": { "Default": "Information", "Override": { "Default": "Information", "System": "Information", "Microsoft": "Information" } }, "WriteTo": [ { "Name": "Console" }, { "Name": "Async", "Args": { "configure": [ { "Name": "File", "Args": { "outputTemplate": "Date:{Timestamp:yyyy-MM-dd HH:mm:ss.fff} LogLevel:{Level} Class:{SourceContext} Message:{Message}{Exception}{NewLine}", "rollingInterval": "4" } } ] } } ] }, "Mysql": { "ConnectionString": "Server=127.0.0.1;Port=3306;database=testlib;uid=root;pwd=sa12345;", "Version": "8.0.20", "MigrationAssembly": "EFCoreEleganceUse.EF.Migrations" } }

2.控制台配置

using Autofac; using Autofac.Extensions.DependencyInjection; using EFCoreEleganceUse.EF.Mysql; using Microsoft.AspNetCore.Builder; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; internal class Program { async static Task Main(string[] args) { //设置当前文件夹 Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory); //注入相关服务启动程序 var host = CreateHostBuilder(args).Build(); host.UseSwagger(); host.UseSwaggerUI(); host.MapControllers(); host.UseAuthentication(); host.UseAuthorization(); await host.RunAsync(); } public static WebApplicationBuilder CreateHostBuilder(string[] args) { //配置参数和环境 var hostBuilder = WebApplication.CreateBuilder(options:new WebApplicationOptions() { Args = args, EnvironmentName = Environments.Development }); //使用日志和aotufac hostBuilder.Host.UseSerilog((context, logger) =>//Serilog { string date = DateTime.Now.ToString("yyyy-MM-dd");//按时间创建文件夹 logger.ReadFrom.Configuration(context.Configuration); logger.Enrich.FromLogContext(); logger.WriteTo.File($"Logs/{date}/", rollingInterval: RollingInterval.Hour);//按小时分日志文件 }).UseServiceProviderFactory(new AutofacServiceProviderFactory()).UseEnvironment(Environments.Development); //生产下需要通过命令行参数或者配置文件设置环境:开发,测试,生产 hostBuilder.Host.ConfigureServices((hostContext, services) => { //注入mysql,生产中应该放置在应用层 var mysqlConfig = hostContext.Configuration.GetSection("Mysql").Get<MysqlOptions>(); var serverVersion = new MariaDbServerVersion(new Version(mysqlConfig.Version)); services.AddDbContext<LibraryDbContext>(options => { options.UseMySql(mysqlConfig.ConnectionString, serverVersion, optionsBuilder => { optionsBuilder.MinBatchSize(4); optionsBuilder.CommandTimeout(10); optionsBuilder.MigrationsAssembly(mysqlConfig.MigrationAssembly); optionsBuilder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery); }).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); if (hostContext.HostingEnvironment.IsDevelopment()) { options.EnableSensitiveDataLogging(); options.EnableDetailedErrors(); } }); services.AddControllers(); services.AddEndpointsApiExplorer(); services.AddSwaggerGen(); }); //注册模块 hostBuilder.Host.ConfigureContainer<ContainerBuilder>((hcontext, containerBuilder) => { //生产中由应用层聚合各种基础设置等模块,最后交由Host程序注册应用层模块 containerBuilder.RegisterModule<EFCoreEleganceUseEFCoreModule>(); }); return hostBuilder; } }

控制台配置最主要的是LibraryDbContext和EFCoreEleganceUseEFCoreModule,下面着重详解

二、EFCore框架DBSet配置详解

1.实体统一配置

EF实体继承统一的接口,方便我们反射获取所有EF实体,接口可以设置一个泛型,来泛化我们的主键类型,因为可能存在不同的表的主键类型也不一样。

接口如下:

public interface IEFEntity<TKey> { public TKey Id { get; set; } }

public abstract class AggregateRoot<TKey> : IEFEntity<TKey> { public TKey Id { get; set; } }

2.实体继承统一接口

public class User : AggregateRoot<string> { public string UserName { get; set; } public DateTime Birthday { get; set; } public virtual ICollection<Book> Books { get; set; } }

public class Book : AggregateRoot<long> { public string BookName { get; set; } public string Author { get; set; } public double Price { get; set; } public string Publisher { get; set; } public string SN { get; set; } //图书序列号 public string? UserId { get; set; } public virtual User? User { get; set; } //租借该书的用户 }

很抱歉,您提供的信息不完整,我无法直接给出答案。请您提供更具体的问题或信息,这样我才能更好地帮助您。

3.获取程序集所有类

public class EFEntityInfo { public (Assembly Assembly, IEnumerable<Type> Types) EFEntitiesInfo => (GetType().Assembly, GetEntityTypes(GetType().Assembly)); private IEnumerable<Type> GetEntityTypes(Assembly assembly) { //获取当前程序集下所有的实现了IEFEntity的实体类 var efEntities = assembly.GetTypes().Where(m => m.FullName != null && Array.Exists(m.GetInterfaces(), t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEFEntity<>)) && !m.IsAbstract && !m.IsInterface).ToArray(); return efEntities; } }

4.批量注入模型类到EF中

using EFCoreEleganceUse.Domain.Entities; using Microsoft.EntityFrameworkCore; namespace EFCoreEleganceUse.EF.Mysql { /// <summary> /// 图书馆数据库上下文 /// </summary> public class LibraryDbContext : DbContext { private readonly EFEntityInfo _efEntitysInfo; public LibraryDbContext(DbContextOptions options, EFEntityInfo efEntityInfo) : base(options) { _efEntitysInfo = efEntityInfo; ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.HasCharSet("utf8mb4 "); var (Assembly, Types) = _efEntitysInfo.EFEntitiesInfo; foreach (var entityType in Types) { modelBuilder.Entity(entityType); } modelBuilder.ApplyConfigurationsFromAssembly(Assembly); base.OnModelCreating(modelBuilder); } } }

所有的实体类都被注册到DBContext中作为DBSets,再也不需要一个个写DBSet了,可以用过DbContext.Set<User>()获取用户的DBSet。

三、EFCore框架表配置详解

1.配置基类,

创建一个配置基类,继承自IEntityTypeConfiguration,做一些通用的配置,比如设置主键,软删除等。

public abstract class EntityTypeConfiguration<TEntity, TKey> : IEntityTypeConfiguration<TEntity> where TEntity : AggregateRoot<TKey> { public virtual void Configure(EntityTypeBuilder<TEntity> builder) { var entityType = typeof(TEntity); builder.HasKey(x => x.Id); if (typeof(ISoftDelete).IsAssignableFrom(entityType)) { builder.HasQueryFilter(d => EF.Property<bool>(d, "IsDeleted") == false); } } }

2.实体表统一配置

public class BookConfig : EntityTypeConfiguration<Book, long> { public override void Configure(EntityTypeBuilder<Book> builder) { base.Configure(builder); builder.Property(x => x.Id).ValueGeneratedOnAdd(); //设置book的id自增 builder.Property(x => x.BookName).HasMaxLength(500).IsRequired(); builder.HasIndex(x => x.Author);//作者添加索引 builder.HasIndex(x => x.SN).IsUnique();//序列号添加唯一索引 builder.HasOne(r => r.User).WithMany(x => x.Books) .HasForeignKey(r => r.UserId).IsRequired(false);//导航属性,本质就是创建外键,虽然查询很方便,生产中不建议使用!!! } }

public class UserConfig : EntityTypeConfiguration<User, string> { public override void Configure(EntityTypeBuilder<User> builder) { base.Configure(builder); builder.Property(x => x.UserName).HasMaxLength(50); //mock一条数据 builder.HasData(new User() { Id = "090213204", UserName = "Bruce", Birthday = DateTime.Parse("1996-08-24") }); } }

3.DBContext中应用配置

using EFCoreEleganceUse.Domain.Entities; using Microsoft.EntityFrameworkCore; namespace EFCoreEleganceUse.EF.Mysql { /// <summary> /// 图书馆数据库上下文 /// </summary> public class LibraryDbContext : DbContext { private readonly EFEntityInfo _efEntitysInfo; public LibraryDbContext(DbContextOptions options, EFEntityInfo efEntityInfo) : base(options) { _efEntitysInfo = efEntityInfo; ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.HasCharSet("utf8mb4 "); var (Assembly, Types) = _efEntitysInfo.EFEntitiesInfo; foreach (var entityType in Types) { modelBuilder.Entity(entityType); } //只需要将配置类所在的程序集给到,它会自动加载 modelBuilder.ApplyConfigurationsFromAssembly(Assembly); base.OnModelCreating(modelBuilder); } } }

四、仓储配置

1.仓储基类

public interface IAsyncRepository<TEntity, Tkey> where TEntity : class { // query IQueryable<TEntity> All(); IQueryable<TEntity> All(string[] propertiesToInclude); IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> filter); IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> filter, string[] propertiesToInclude); }

2.仓储实现类

public class GenericRepository<TEntity, Tkey> : IAsyncRepository<TEntity, Tkey> where TEntity : class { protected readonly LibraryDbContext _dbContext; public GenericRepository(LibraryDbContext dbContext) { _dbContext = dbContext; } ~GenericRepository() { _dbContext?.Dispose(); } public virtual IQueryable<TEntity> All() { return All(null); } public virtual IQueryable<TEntity> All(string[] propertiesToInclude) { var query = _dbContext.Set<TEntity>().AsNoTracking(); if (propertiesToInclude != null) { foreach (var property in propertiesToInclude.Where(p => !string.IsNullOrWhiteSpace(p))) { query = query.Include(property); } } return query; } public virtual IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> filter) { return Where(filter, null); } public virtual IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> filter, string[] propertiesToInclude) { var query = _dbContext.Set<TEntity>().AsNoTracking(); if (filter != null) { query = query.Where(filter); } if (propertiesToInclude != null) { foreach (var property in propertiesToInclude.Where(p => !string.IsNullOrWhiteSpace(p))) { query = query.Include(property); } } return query; } }

五、Autofac配置

1.注入DBContext到Repository

public class EFCoreEleganceUseEFCoreModule : Module { protected override void Load(ContainerBuilder builder) { base.Load(builder); builder.RegisterModule<EFCoreEleganceUseDomainModule>(); //注入domain模块 builder.RegisterGeneric(typeof(GenericRepository<,>))//将dbcontext注入到仓储的构造中 .UsingConstructor(typeof(LibraryDbContext)) .AsImplementedInterfaces() .InstancePerDependency(); builder.RegisterType<WorkUnit>().As<IWorkUnit>().InstancePerDependency(); } }

2.Domain注入EFEntityInfo

public class EFCoreEleganceUseDomainModule : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterType<EFEntityInfo>().SingleInstance(); } }

六、运行

1.数据库迁移

官方文档如下:learn.microsoft.com/zh-cn/ef/core/managing-schemas/migrations/managing?tabs=vs

Add-Migration InitialCreate -OutputDir Your\Directory Update-Database

2.Users控制器

[ApiController] [Route("[controller]")] public class UsersController : ControllerBase { private readonly ILogger<UsersController> _logger; //生产中可以在应用层下创建service层,聚合各种实体仓储 private readonly IAsyncRepository<User, string> _userAsyncRepository; public UsersController(ILogger<UsersController> logger, IAsyncRepository<User, string> userAsyncRepository) { _logger = logger; _userAsyncRepository = userAsyncRepository; } [HttpGet] [AllowAnonymous] public async Task<ActionResult> Get() { return Ok(await _userAsyncRepository.All().ToListAsync()); } }

相关源码:download.csdn.net/download/aa2528877987/87474302

本文共计2095个文字,预计阅读时间需要9分钟。

很抱歉,您提供的信息不完整,我无法直接给出答案。请您提供更具体的问题或信息,这样我才能更好地帮助您。

前言:WebAPI是一种协议,用于允许网络应用程序(如浏览器)与网络服务器(如Web服务器)之间进行通信。它可以处理数据、访问数据库、处理图像和视频,以及执行其他高级功能。

前言

WebAPI是一种协议,用于允许网络应用程序(如浏览器)与网络服务器(如Web服务器)之间进行通信。它可以用于处理数据,访问数据库,处理图像和视频,以及进行其他高级功能。

本文涉及的知识量巨大主要有如下:

  • EFCore
  • Autofac
  • Serilog
  • Swagger
  • 非常多底层知识

一、使用控制台手搭webapi框架

1.配置文件

appsettings.Development.json

{ "Serilog": { "MinimumLevel": { "Default": "Information", "Override": { "Default": "Information", "System": "Information", "Microsoft": "Information" } }, "WriteTo": [ { "Name": "Console" }, { "Name": "Async", "Args": { "configure": [ { "Name": "File", "Args": { "outputTemplate": "Date:{Timestamp:yyyy-MM-dd HH:mm:ss.fff} LogLevel:{Level} Class:{SourceContext} Message:{Message}{Exception}{NewLine}", "rollingInterval": "4" } } ] } } ] }, "Mysql": { "ConnectionString": "Server=127.0.0.1;Port=3306;database=testlib;uid=root;pwd=sa12345;", "Version": "8.0.20", "MigrationAssembly": "EFCoreEleganceUse.EF.Migrations" } }

2.控制台配置

using Autofac; using Autofac.Extensions.DependencyInjection; using EFCoreEleganceUse.EF.Mysql; using Microsoft.AspNetCore.Builder; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; internal class Program { async static Task Main(string[] args) { //设置当前文件夹 Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory); //注入相关服务启动程序 var host = CreateHostBuilder(args).Build(); host.UseSwagger(); host.UseSwaggerUI(); host.MapControllers(); host.UseAuthentication(); host.UseAuthorization(); await host.RunAsync(); } public static WebApplicationBuilder CreateHostBuilder(string[] args) { //配置参数和环境 var hostBuilder = WebApplication.CreateBuilder(options:new WebApplicationOptions() { Args = args, EnvironmentName = Environments.Development }); //使用日志和aotufac hostBuilder.Host.UseSerilog((context, logger) =>//Serilog { string date = DateTime.Now.ToString("yyyy-MM-dd");//按时间创建文件夹 logger.ReadFrom.Configuration(context.Configuration); logger.Enrich.FromLogContext(); logger.WriteTo.File($"Logs/{date}/", rollingInterval: RollingInterval.Hour);//按小时分日志文件 }).UseServiceProviderFactory(new AutofacServiceProviderFactory()).UseEnvironment(Environments.Development); //生产下需要通过命令行参数或者配置文件设置环境:开发,测试,生产 hostBuilder.Host.ConfigureServices((hostContext, services) => { //注入mysql,生产中应该放置在应用层 var mysqlConfig = hostContext.Configuration.GetSection("Mysql").Get<MysqlOptions>(); var serverVersion = new MariaDbServerVersion(new Version(mysqlConfig.Version)); services.AddDbContext<LibraryDbContext>(options => { options.UseMySql(mysqlConfig.ConnectionString, serverVersion, optionsBuilder => { optionsBuilder.MinBatchSize(4); optionsBuilder.CommandTimeout(10); optionsBuilder.MigrationsAssembly(mysqlConfig.MigrationAssembly); optionsBuilder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery); }).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); if (hostContext.HostingEnvironment.IsDevelopment()) { options.EnableSensitiveDataLogging(); options.EnableDetailedErrors(); } }); services.AddControllers(); services.AddEndpointsApiExplorer(); services.AddSwaggerGen(); }); //注册模块 hostBuilder.Host.ConfigureContainer<ContainerBuilder>((hcontext, containerBuilder) => { //生产中由应用层聚合各种基础设置等模块,最后交由Host程序注册应用层模块 containerBuilder.RegisterModule<EFCoreEleganceUseEFCoreModule>(); }); return hostBuilder; } }

控制台配置最主要的是LibraryDbContext和EFCoreEleganceUseEFCoreModule,下面着重详解

二、EFCore框架DBSet配置详解

1.实体统一配置

EF实体继承统一的接口,方便我们反射获取所有EF实体,接口可以设置一个泛型,来泛化我们的主键类型,因为可能存在不同的表的主键类型也不一样。

接口如下:

public interface IEFEntity<TKey> { public TKey Id { get; set; } }

public abstract class AggregateRoot<TKey> : IEFEntity<TKey> { public TKey Id { get; set; } }

2.实体继承统一接口

public class User : AggregateRoot<string> { public string UserName { get; set; } public DateTime Birthday { get; set; } public virtual ICollection<Book> Books { get; set; } }

public class Book : AggregateRoot<long> { public string BookName { get; set; } public string Author { get; set; } public double Price { get; set; } public string Publisher { get; set; } public string SN { get; set; } //图书序列号 public string? UserId { get; set; } public virtual User? User { get; set; } //租借该书的用户 }

很抱歉,您提供的信息不完整,我无法直接给出答案。请您提供更具体的问题或信息,这样我才能更好地帮助您。

3.获取程序集所有类

public class EFEntityInfo { public (Assembly Assembly, IEnumerable<Type> Types) EFEntitiesInfo => (GetType().Assembly, GetEntityTypes(GetType().Assembly)); private IEnumerable<Type> GetEntityTypes(Assembly assembly) { //获取当前程序集下所有的实现了IEFEntity的实体类 var efEntities = assembly.GetTypes().Where(m => m.FullName != null && Array.Exists(m.GetInterfaces(), t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEFEntity<>)) && !m.IsAbstract && !m.IsInterface).ToArray(); return efEntities; } }

4.批量注入模型类到EF中

using EFCoreEleganceUse.Domain.Entities; using Microsoft.EntityFrameworkCore; namespace EFCoreEleganceUse.EF.Mysql { /// <summary> /// 图书馆数据库上下文 /// </summary> public class LibraryDbContext : DbContext { private readonly EFEntityInfo _efEntitysInfo; public LibraryDbContext(DbContextOptions options, EFEntityInfo efEntityInfo) : base(options) { _efEntitysInfo = efEntityInfo; ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.HasCharSet("utf8mb4 "); var (Assembly, Types) = _efEntitysInfo.EFEntitiesInfo; foreach (var entityType in Types) { modelBuilder.Entity(entityType); } modelBuilder.ApplyConfigurationsFromAssembly(Assembly); base.OnModelCreating(modelBuilder); } } }

所有的实体类都被注册到DBContext中作为DBSets,再也不需要一个个写DBSet了,可以用过DbContext.Set<User>()获取用户的DBSet。

三、EFCore框架表配置详解

1.配置基类,

创建一个配置基类,继承自IEntityTypeConfiguration,做一些通用的配置,比如设置主键,软删除等。

public abstract class EntityTypeConfiguration<TEntity, TKey> : IEntityTypeConfiguration<TEntity> where TEntity : AggregateRoot<TKey> { public virtual void Configure(EntityTypeBuilder<TEntity> builder) { var entityType = typeof(TEntity); builder.HasKey(x => x.Id); if (typeof(ISoftDelete).IsAssignableFrom(entityType)) { builder.HasQueryFilter(d => EF.Property<bool>(d, "IsDeleted") == false); } } }

2.实体表统一配置

public class BookConfig : EntityTypeConfiguration<Book, long> { public override void Configure(EntityTypeBuilder<Book> builder) { base.Configure(builder); builder.Property(x => x.Id).ValueGeneratedOnAdd(); //设置book的id自增 builder.Property(x => x.BookName).HasMaxLength(500).IsRequired(); builder.HasIndex(x => x.Author);//作者添加索引 builder.HasIndex(x => x.SN).IsUnique();//序列号添加唯一索引 builder.HasOne(r => r.User).WithMany(x => x.Books) .HasForeignKey(r => r.UserId).IsRequired(false);//导航属性,本质就是创建外键,虽然查询很方便,生产中不建议使用!!! } }

public class UserConfig : EntityTypeConfiguration<User, string> { public override void Configure(EntityTypeBuilder<User> builder) { base.Configure(builder); builder.Property(x => x.UserName).HasMaxLength(50); //mock一条数据 builder.HasData(new User() { Id = "090213204", UserName = "Bruce", Birthday = DateTime.Parse("1996-08-24") }); } }

3.DBContext中应用配置

using EFCoreEleganceUse.Domain.Entities; using Microsoft.EntityFrameworkCore; namespace EFCoreEleganceUse.EF.Mysql { /// <summary> /// 图书馆数据库上下文 /// </summary> public class LibraryDbContext : DbContext { private readonly EFEntityInfo _efEntitysInfo; public LibraryDbContext(DbContextOptions options, EFEntityInfo efEntityInfo) : base(options) { _efEntitysInfo = efEntityInfo; ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.HasCharSet("utf8mb4 "); var (Assembly, Types) = _efEntitysInfo.EFEntitiesInfo; foreach (var entityType in Types) { modelBuilder.Entity(entityType); } //只需要将配置类所在的程序集给到,它会自动加载 modelBuilder.ApplyConfigurationsFromAssembly(Assembly); base.OnModelCreating(modelBuilder); } } }

四、仓储配置

1.仓储基类

public interface IAsyncRepository<TEntity, Tkey> where TEntity : class { // query IQueryable<TEntity> All(); IQueryable<TEntity> All(string[] propertiesToInclude); IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> filter); IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> filter, string[] propertiesToInclude); }

2.仓储实现类

public class GenericRepository<TEntity, Tkey> : IAsyncRepository<TEntity, Tkey> where TEntity : class { protected readonly LibraryDbContext _dbContext; public GenericRepository(LibraryDbContext dbContext) { _dbContext = dbContext; } ~GenericRepository() { _dbContext?.Dispose(); } public virtual IQueryable<TEntity> All() { return All(null); } public virtual IQueryable<TEntity> All(string[] propertiesToInclude) { var query = _dbContext.Set<TEntity>().AsNoTracking(); if (propertiesToInclude != null) { foreach (var property in propertiesToInclude.Where(p => !string.IsNullOrWhiteSpace(p))) { query = query.Include(property); } } return query; } public virtual IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> filter) { return Where(filter, null); } public virtual IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> filter, string[] propertiesToInclude) { var query = _dbContext.Set<TEntity>().AsNoTracking(); if (filter != null) { query = query.Where(filter); } if (propertiesToInclude != null) { foreach (var property in propertiesToInclude.Where(p => !string.IsNullOrWhiteSpace(p))) { query = query.Include(property); } } return query; } }

五、Autofac配置

1.注入DBContext到Repository

public class EFCoreEleganceUseEFCoreModule : Module { protected override void Load(ContainerBuilder builder) { base.Load(builder); builder.RegisterModule<EFCoreEleganceUseDomainModule>(); //注入domain模块 builder.RegisterGeneric(typeof(GenericRepository<,>))//将dbcontext注入到仓储的构造中 .UsingConstructor(typeof(LibraryDbContext)) .AsImplementedInterfaces() .InstancePerDependency(); builder.RegisterType<WorkUnit>().As<IWorkUnit>().InstancePerDependency(); } }

2.Domain注入EFEntityInfo

public class EFCoreEleganceUseDomainModule : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterType<EFEntityInfo>().SingleInstance(); } }

六、运行

1.数据库迁移

官方文档如下:learn.microsoft.com/zh-cn/ef/core/managing-schemas/migrations/managing?tabs=vs

Add-Migration InitialCreate -OutputDir Your\Directory Update-Database

2.Users控制器

[ApiController] [Route("[controller]")] public class UsersController : ControllerBase { private readonly ILogger<UsersController> _logger; //生产中可以在应用层下创建service层,聚合各种实体仓储 private readonly IAsyncRepository<User, string> _userAsyncRepository; public UsersController(ILogger<UsersController> logger, IAsyncRepository<User, string> userAsyncRepository) { _logger = logger; _userAsyncRepository = userAsyncRepository; } [HttpGet] [AllowAnonymous] public async Task<ActionResult> Get() { return Ok(await _userAsyncRepository.All().ToListAsync()); } }

相关源码:download.csdn.net/download/aa2528877987/87474302