diff --git a/Examples/repository_01/Controllers/SongController.cs b/Examples/repository_01/Controllers/SongController.cs new file mode 100644 index 00000000..20b0d825 --- /dev/null +++ b/Examples/repository_01/Controllers/SongController.cs @@ -0,0 +1,57 @@ +using Microsoft.AspNetCore.Mvc; +using repository_01.Repositorys; +using restful.Entitys; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace restful.Controllers { + + + [Route("restapi/[controller]")] + public class SongsController : Controller { + + SongRepository _songRepository; + + public SongsController(IFreeSql fsql) { + _songRepository = new SongRepository(fsql); + } + + [HttpGet] + public Task> GetItems([FromQuery] string key, [FromQuery] int page = 1, [FromQuery] int limit = 20) { + return _songRepository.Select.WhereIf(!string.IsNullOrEmpty(key), a => a.Title.Contains(key)).Page(page, limit).ToListAsync(); + } + + [HttpGet("{id}")] + public Task GetItem([FromRoute] int id) { + return _songRepository.FindAsync(id); + } + + public class ModelSong { + public string title { get; set; } + } + + [HttpPost, ProducesResponseType(201)] + public Task Create([FromBody] ModelSong model) { + return _songRepository.InsertAsync(new Song { Title = model.title }); + } + + [HttpPut("{id}")] + public Task Update([FromRoute] int id, [FromBody] ModelSong model) { + return _songRepository.UpdateAsync(new Song { Id = id, Title = model.title }); + } + + [HttpPatch("{id}")] + async public Task UpdateDiy([FromRoute] int id, [FromForm] string title) { + var up = _songRepository.UpdateDiy.Where(a => a.Id == id); + if (!string.IsNullOrEmpty(title)) up.Set(a => a.Title, title); + var ret = await up.ExecuteUpdatedAsync(); + return ret.FirstOrDefault(); + } + + [HttpDelete("{id}"), ProducesResponseType(204)] + public Task Delete([FromRoute] int id) { + return _songRepository.DeleteAsync(a => a.Id == id); + } + } +} diff --git a/Examples/repository_01/Entitys/Song.cs b/Examples/repository_01/Entitys/Song.cs new file mode 100644 index 00000000..f91f2505 --- /dev/null +++ b/Examples/repository_01/Entitys/Song.cs @@ -0,0 +1,10 @@ +using FreeSql.DataAnnotations; + +namespace restful.Entitys { + public class Song { + + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Title { get; set; } + } +} diff --git a/Examples/repository_01/Program.cs b/Examples/repository_01/Program.cs new file mode 100644 index 00000000..da7591b3 --- /dev/null +++ b/Examples/repository_01/Program.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace repository_01 +{ + public class Program + { + public static void Main(string[] args) + { + CreateWebHostBuilder(args).Build().Run(); + } + + public static IWebHostBuilder CreateWebHostBuilder(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup(); + } +} diff --git a/Examples/repository_01/Repositorys/SongRepository.cs b/Examples/repository_01/Repositorys/SongRepository.cs new file mode 100644 index 00000000..1009b3a8 --- /dev/null +++ b/Examples/repository_01/Repositorys/SongRepository.cs @@ -0,0 +1,13 @@ +using FreeSql; +using restful.Entitys; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace repository_01.Repositorys { + public class SongRepository : BaseRepository { + public SongRepository(IFreeSql fsql) : base(fsql) { + } + } +} diff --git a/Examples/repository_01/Startup.cs b/Examples/repository_01/Startup.cs new file mode 100644 index 00000000..f827dfe5 --- /dev/null +++ b/Examples/repository_01/Startup.cs @@ -0,0 +1,57 @@ +using FreeSql; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Swashbuckle.AspNetCore.Swagger; +using System; +using System.Text; + +namespace repository_01 { + public class Startup { + public Startup(IConfiguration configuration, ILoggerFactory loggerFactory) { + Configuration = configuration; + + Fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10") + .UseLogger(loggerFactory.CreateLogger()) + .UseAutoSyncStructure(true) + .Build(); + } + + public IConfiguration Configuration { get; } + public IFreeSql Fsql { get; } + + public void ConfigureServices(IServiceCollection services) { + services.AddSingleton(Fsql); + + services.AddMvc(); + services.AddSwaggerGen(options => { + options.SwaggerDoc("v1", new Info { + Version = "v1", + Title = "FreeSql.RESTful API" + }); + //options.IncludeXmlComments(xmlPath); + }); + } + + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + Console.OutputEncoding = Encoding.GetEncoding("GB2312"); + Console.InputEncoding = Encoding.GetEncoding("GB2312"); + + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); + + app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" }); + app.UseDeveloperExceptionPage(); + app.UseMvc(); + + app.UseSwagger(); + app.UseSwaggerUI(c => { + c.SwaggerEndpoint("/swagger/v1/swagger.json", "FreeSql.RESTful API V1"); + }); + } + } +} diff --git a/Examples/repository_01/appsettings.Development.json b/Examples/repository_01/appsettings.Development.json new file mode 100644 index 00000000..e203e940 --- /dev/null +++ b/Examples/repository_01/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/Examples/repository_01/appsettings.json b/Examples/repository_01/appsettings.json new file mode 100644 index 00000000..def9159a --- /dev/null +++ b/Examples/repository_01/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Examples/repository_01/repository_01.csproj b/Examples/repository_01/repository_01.csproj new file mode 100644 index 00000000..bb3ba347 --- /dev/null +++ b/Examples/repository_01/repository_01.csproj @@ -0,0 +1,23 @@ + + + + netcoreapp2.2 + InProcess + + + + + + + + + + + + + + + + + + diff --git a/Examples/restful/Controllers/EntityController.cs b/Examples/restful/Controllers/SongController.cs similarity index 100% rename from Examples/restful/Controllers/EntityController.cs rename to Examples/restful/Controllers/SongController.cs diff --git a/Examples/restful/Startup.cs b/Examples/restful/Startup.cs index deb084ab..ac6c5817 100644 --- a/Examples/restful/Startup.cs +++ b/Examples/restful/Startup.cs @@ -8,11 +8,9 @@ using System; using System.Text; namespace restful { - public class Startup - { - public Startup(IConfiguration configuration, ILoggerFactory loggerFactory) - { - Configuration = configuration; + public class Startup { + public Startup(IConfiguration configuration, ILoggerFactory loggerFactory) { + Configuration = configuration; Fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") @@ -21,16 +19,14 @@ namespace restful { .Build(); } - public IConfiguration Configuration { get; } + public IConfiguration Configuration { get; } public IFreeSql Fsql { get; } - public void ConfigureServices(IServiceCollection services) - { + public void ConfigureServices(IServiceCollection services) { services.AddSingleton(Fsql); - services.AddMvc(); - services.AddSwaggerGen(options => - { + services.AddMvc(); + services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new Info { Version = "v1", Title = "FreeSql.RESTful API" @@ -39,8 +35,7 @@ namespace restful { }); } - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) - { + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Console.OutputEncoding = Encoding.GetEncoding("GB2312"); Console.InputEncoding = Encoding.GetEncoding("GB2312"); @@ -53,10 +48,9 @@ namespace restful { app.UseMvc(); app.UseSwagger(); - app.UseSwaggerUI(c => - { + app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "FreeSql.RESTful API V1"); }); } - } + } } diff --git a/FreeSql.Repository/BaseRepository.cs b/FreeSql.Repository/BaseRepository.cs new file mode 100644 index 00000000..2c2c9fd5 --- /dev/null +++ b/FreeSql.Repository/BaseRepository.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql { + public abstract class BaseRepository : IRepository + where TEntity : class { + + protected IFreeSql _fsql; + + public BaseRepository(IFreeSql fsql) : base() { + _fsql = fsql; + if (_fsql == null) throw new NullReferenceException("fsql 参数不可为空"); + } + + public ISelect Select => _fsql.Select(); + + public IUpdate UpdateDiy => _fsql.Update(); + + public void Delete(Expression> predicate) => _fsql.Delete().Where(predicate).ExecuteAffrows(); + + public void Delete(TEntity entity) => _fsql.Delete(entity).ExecuteAffrows(); + + public Task DeleteAsync(Expression> predicate) => _fsql.Delete().Where(predicate).ExecuteAffrowsAsync(); + + public Task DeleteAsync(TEntity entity) => _fsql.Delete(entity).ExecuteAffrowsAsync(); + + public TEntity Insert(TEntity entity) => _fsql.Insert().AppendData(entity).ExecuteInserted().FirstOrDefault(); + + async public Task InsertAsync(TEntity entity) => (await _fsql.Insert().AppendData(entity).ExecuteInsertedAsync()).FirstOrDefault(); + + public void Update(TEntity entity) => _fsql.Update().SetSource(entity).ExecuteAffrows(); + + public Task UpdateAsync(TEntity entity) => _fsql.Update().SetSource(entity).ExecuteAffrowsAsync(); + } + + public abstract class BaseRepository : BaseRepository, IRepository + where TEntity : class { + + public BaseRepository(IFreeSql fsql) : base(fsql) { + } + + public void Delete(TKey id) => _fsql.Delete(id).ExecuteAffrows(); + + public Task DeleteAsync(TKey id) => _fsql.Delete(id).ExecuteAffrowsAsync(); + + public TEntity Find(TKey id) => _fsql.Select(id).ToOne(); + + public Task FindAsync(TKey id) => _fsql.Select(id).ToOneAsync(); + + public TEntity Get(TKey id) => Find(id); + + public Task GetAsync(TKey id) => FindAsync(id); + } +} diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj new file mode 100644 index 00000000..97f3eb85 --- /dev/null +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -0,0 +1,11 @@ + + + + netstandard2.0 + + + + + + + diff --git a/FreeSql.Repository/IBasicRepository.cs b/FreeSql.Repository/IBasicRepository.cs new file mode 100644 index 00000000..95d7ebdb --- /dev/null +++ b/FreeSql.Repository/IBasicRepository.cs @@ -0,0 +1,28 @@ +using System.Threading.Tasks; + +namespace FreeSql { + public interface IBasicRepository : IReadOnlyRepository + where TEntity : class { + TEntity Insert(TEntity entity); + + Task InsertAsync(TEntity entity); + + void Update(TEntity entity); + + Task UpdateAsync(TEntity entity); + + IUpdate UpdateDiy { get; } + + void Delete(TEntity entity); + + Task DeleteAsync(TEntity entity); + } + + public interface IBasicRepository : IBasicRepository, IReadOnlyRepository + where TEntity : class { + void Delete(TKey id); + + Task DeleteAsync(TKey id); + } +} + diff --git a/FreeSql.Repository/IReadOnlyRepository.cs b/FreeSql.Repository/IReadOnlyRepository.cs new file mode 100644 index 00000000..bd26e7e8 --- /dev/null +++ b/FreeSql.Repository/IReadOnlyRepository.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace FreeSql { + public interface IReadOnlyRepository : IRepository + where TEntity : class { + + ISelect Select { get; } + } + + public interface IReadOnlyRepository : IReadOnlyRepository + where TEntity : class { + TEntity Get(TKey id); + + Task GetAsync(TKey id); + + TEntity Find(TKey id); + + Task FindAsync(TKey id); + } +} diff --git a/FreeSql.Repository/IRepository.cs b/FreeSql.Repository/IRepository.cs new file mode 100644 index 00000000..309ea461 --- /dev/null +++ b/FreeSql.Repository/IRepository.cs @@ -0,0 +1,21 @@ +using System; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace FreeSql { + + public interface IRepository { + + } + + public interface IRepository : IReadOnlyRepository, IBasicRepository + where TEntity : class { + void Delete(Expression> predicate); + + Task DeleteAsync(Expression> predicate); + } + + public interface IRepository : IRepository, IReadOnlyRepository, IBasicRepository + where TEntity : class { + } +} \ No newline at end of file diff --git a/FreeSql.sln b/FreeSql.sln index 3de6b5fd..e51a6330 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -14,7 +14,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{C6A74E2A-6 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.PerformanceTests", "FreeSql.Tests.PerformanceTests\FreeSql.Tests.PerformanceTests.csproj", "{446D9CBE-BFE4-4FB3-ADFD-4C1C5EA1B6EE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Extensions.EFCoreModelBuilder", "FreeSql.Extensions.EFCoreModelBuilder\FreeSql.Extensions.EFCoreModelBuilder.csproj", "{490CC8AF-C47C-4139-AED7-4FB6502F622B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.EFCoreModelBuilder", "FreeSql.Extensions.EFCoreModelBuilder\FreeSql.Extensions.EFCoreModelBuilder.csproj", "{490CC8AF-C47C-4139-AED7-4FB6502F622B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{94C8A78D-AA15-47B2-A348-530CD86BFC1B}" EndProject @@ -22,6 +22,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "restful", "Examples\restful EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "efcore_to_freesql", "Examples\efcore_to_freesql\efcore_to_freesql.csproj", "{B93981B8-3295-4EDD-B314-BCA77B6BF37A}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Repository", "FreeSql.Repository\FreeSql.Repository.csproj", "{AC47670E-90BB-4502-9965-0739BDF6FE2E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "repository_01", "Examples\repository_01\repository_01.csproj", "{C9940A46-D265-4088-9561-5A42ACEDA7AE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -104,6 +108,30 @@ Global {B93981B8-3295-4EDD-B314-BCA77B6BF37A}.Release|x64.Build.0 = Release|Any CPU {B93981B8-3295-4EDD-B314-BCA77B6BF37A}.Release|x86.ActiveCfg = Release|Any CPU {B93981B8-3295-4EDD-B314-BCA77B6BF37A}.Release|x86.Build.0 = Release|Any CPU + {AC47670E-90BB-4502-9965-0739BDF6FE2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC47670E-90BB-4502-9965-0739BDF6FE2E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC47670E-90BB-4502-9965-0739BDF6FE2E}.Debug|x64.ActiveCfg = Debug|Any CPU + {AC47670E-90BB-4502-9965-0739BDF6FE2E}.Debug|x64.Build.0 = Debug|Any CPU + {AC47670E-90BB-4502-9965-0739BDF6FE2E}.Debug|x86.ActiveCfg = Debug|Any CPU + {AC47670E-90BB-4502-9965-0739BDF6FE2E}.Debug|x86.Build.0 = Debug|Any CPU + {AC47670E-90BB-4502-9965-0739BDF6FE2E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC47670E-90BB-4502-9965-0739BDF6FE2E}.Release|Any CPU.Build.0 = Release|Any CPU + {AC47670E-90BB-4502-9965-0739BDF6FE2E}.Release|x64.ActiveCfg = Release|Any CPU + {AC47670E-90BB-4502-9965-0739BDF6FE2E}.Release|x64.Build.0 = Release|Any CPU + {AC47670E-90BB-4502-9965-0739BDF6FE2E}.Release|x86.ActiveCfg = Release|Any CPU + {AC47670E-90BB-4502-9965-0739BDF6FE2E}.Release|x86.Build.0 = Release|Any CPU + {C9940A46-D265-4088-9561-5A42ACEDA7AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C9940A46-D265-4088-9561-5A42ACEDA7AE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C9940A46-D265-4088-9561-5A42ACEDA7AE}.Debug|x64.ActiveCfg = Debug|Any CPU + {C9940A46-D265-4088-9561-5A42ACEDA7AE}.Debug|x64.Build.0 = Debug|Any CPU + {C9940A46-D265-4088-9561-5A42ACEDA7AE}.Debug|x86.ActiveCfg = Debug|Any CPU + {C9940A46-D265-4088-9561-5A42ACEDA7AE}.Debug|x86.Build.0 = Debug|Any CPU + {C9940A46-D265-4088-9561-5A42ACEDA7AE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C9940A46-D265-4088-9561-5A42ACEDA7AE}.Release|Any CPU.Build.0 = Release|Any CPU + {C9940A46-D265-4088-9561-5A42ACEDA7AE}.Release|x64.ActiveCfg = Release|Any CPU + {C9940A46-D265-4088-9561-5A42ACEDA7AE}.Release|x64.Build.0 = Release|Any CPU + {C9940A46-D265-4088-9561-5A42ACEDA7AE}.Release|x86.ActiveCfg = Release|Any CPU + {C9940A46-D265-4088-9561-5A42ACEDA7AE}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -111,6 +139,7 @@ Global GlobalSection(NestedProjects) = preSolution {83D10565-AF9D-4EDC-8FB8-8C962A843F97} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {B93981B8-3295-4EDD-B314-BCA77B6BF37A} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} + {C9940A46-D265-4088-9561-5A42ACEDA7AE} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98}