diff --git a/Examples/dbcontext_01/Controllers/ValuesController.cs b/Examples/dbcontext_01/Controllers/ValuesController.cs new file mode 100644 index 00000000..47fa3fe6 --- /dev/null +++ b/Examples/dbcontext_01/Controllers/ValuesController.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace dbcontext_01.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class ValuesController : ControllerBase + { + + IFreeSql _orm; + public ValuesController(SongContext songContext, IFreeSql orm) { + + _orm = orm; + + } + + // GET api/values + [HttpGet] + async public Task Get() + { + + long id = 0; + + try { + using (var ctx = new SongContext()) { + + id = await ctx.Songs.Insert(new Song { }).ExecuteIdentityAsync(); + + var item = await ctx.Songs.Select.Where(a => a.Id == id).FirstAsync(); + + throw new Exception("回滚"); + + } + } catch { + var item = await _orm.Select().Where(a => a.Id == id).FirstAsync(); + + throw; + } + } + + // GET api/values/5 + [HttpGet("{id}")] + public ActionResult Get(int id) + { + return "value"; + } + + // POST api/values + [HttpPost] + public void Post([FromBody] string value) + { + } + + // PUT api/values/5 + [HttpPut("{id}")] + public void Put(int id, [FromBody] string value) + { + } + + // DELETE api/values/5 + [HttpDelete("{id}")] + public void Delete(int id) + { + } + } +} diff --git a/Examples/dbcontext_01/DbContexts/SongContext.cs b/Examples/dbcontext_01/DbContexts/SongContext.cs new file mode 100644 index 00000000..d1a01cd3 --- /dev/null +++ b/Examples/dbcontext_01/DbContexts/SongContext.cs @@ -0,0 +1,49 @@ +using FreeSql; +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; + +namespace dbcontext_01 { + + public class SongContext : DbContext { + + public DbSet Songs { get; set; } + public DbSet Tags { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder builder) { + builder.UseFreeSql(dbcontext_01.Startup.Fsql); + } + } + + + public class Song { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public class Song_tag { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + + public class Tag { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } +} diff --git a/Examples/dbcontext_01/Program.cs b/Examples/dbcontext_01/Program.cs new file mode 100644 index 00000000..6c883ccf --- /dev/null +++ b/Examples/dbcontext_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 dbcontext_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/dbcontext_01/Startup.cs b/Examples/dbcontext_01/Startup.cs new file mode 100644 index 00000000..a7e3965a --- /dev/null +++ b/Examples/dbcontext_01/Startup.cs @@ -0,0 +1,68 @@ +using FreeSql; +using FreeSql.DataAnnotations; +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.Diagnostics; +using System.Linq; +using System.Text; + +namespace dbcontext_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) + .UseLazyLoading(true) + + .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) + .Build(); + } + + public IConfiguration Configuration { get; } + public static IFreeSql Fsql { get; private set; } + + public void ConfigureServices(IServiceCollection services) + { + services.AddMvc(); + services.AddSwaggerGen(options => { + options.SwaggerDoc("v1", new Info { + Version = "v1", + Title = "FreeSql.DbContext API" + }); + //options.IncludeXmlComments(xmlPath); + }); + + services.AddSingleton(Fsql); + services.AddFreeDbContext(options => options.UseFreeSql(Fsql)); + } + + 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/dbcontext_01/appsettings.Development.json b/Examples/dbcontext_01/appsettings.Development.json new file mode 100644 index 00000000..e203e940 --- /dev/null +++ b/Examples/dbcontext_01/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/Examples/dbcontext_01/appsettings.json b/Examples/dbcontext_01/appsettings.json new file mode 100644 index 00000000..def9159a --- /dev/null +++ b/Examples/dbcontext_01/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Examples/dbcontext_01/dbcontext_01.csproj b/Examples/dbcontext_01/dbcontext_01.csproj new file mode 100644 index 00000000..480916b7 --- /dev/null +++ b/Examples/dbcontext_01/dbcontext_01.csproj @@ -0,0 +1,19 @@ + + + + netcoreapp2.1 + InProcess + + + + + + + + + + + + + + diff --git a/Examples/repository_01/Startup.cs b/Examples/repository_01/Startup.cs index 13b97c87..0baf7025 100644 --- a/Examples/repository_01/Startup.cs +++ b/Examples/repository_01/Startup.cs @@ -51,7 +51,7 @@ namespace repository_01 { } public IConfiguration Configuration { get; } - public IFreeSql Fsql { get; } + public static IFreeSql Fsql { get; private set; } public IServiceProvider ConfigureServices(IServiceCollection services) { diff --git a/FreeSql.DbContext/DbContext.cs b/FreeSql.DbContext/DbContext.cs new file mode 100644 index 00000000..6f46dd79 --- /dev/null +++ b/FreeSql.DbContext/DbContext.cs @@ -0,0 +1,94 @@ +using SafeObjectPool; +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Data.Common; +using System.Linq; +using System.Reflection; + +namespace FreeSql { + public abstract class DbContext : IDisposable { + + internal IFreeSql _orm; + internal IFreeSql _fsql => _orm ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); + + Object _conn; + DbTransaction _tran; + + static ConcurrentDictionary _dicGetDbSetProps = new ConcurrentDictionary(); + protected DbContext() { + + var builder = new DbContextOptionsBuilder(); + OnConfiguring(builder); + _orm = builder._fsql; + + var props = _dicGetDbSetProps.GetOrAdd(this.GetType(), tp => + tp.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public) + .Where(a => a.PropertyType.IsGenericType && + a.PropertyType == typeof(DbSet<>).MakeGenericType(a.PropertyType.GenericTypeArguments[0])).ToArray()); + + foreach (var prop in props) { + var set = this.Set(prop.PropertyType.GenericTypeArguments[0]); + + prop.SetValue(this, set); + AllSets.Add(prop, set); + } + } + + protected virtual void OnConfiguring(DbContextOptionsBuilder builder) { + + } + + public DbSet Set() where TEntity : class => this.Set(typeof(TEntity)) as DbSet; + public object Set(Type entityType) => Activator.CreateInstance(typeof(BaseDbSet<>).MakeGenericType(entityType), this); + + protected Dictionary AllSets => new Dictionary(); + + public void SaveChanges() { + Commit(); + } + + void ReturnObject() { + _fsql.Ado.MasterPool.Return(_conn); + _tran = null; + _conn = null; + } + internal DbTransaction GetOrBeginTransaction(bool isCreate = true) { + + if (_tran != null) return _tran; + if (isCreate == false) return null; + if (_conn != null) _fsql.Ado.MasterPool.Return(_conn); + + _conn = _fsql.Ado.MasterPool.Get(); + try { + _tran = _conn.Value.BeginTransaction(); + } catch { + ReturnObject(); + throw; + } + return _tran; + } + + void Commit() { + if (_tran != null) { + try { + _tran.Commit(); + } finally { + ReturnObject(); + } + } + } + void Rollback() { + if (_tran != null) { + try { + _tran.Rollback(); + } finally { + ReturnObject(); + } + } + } + public void Dispose() { + this.Rollback(); + } + } +} diff --git a/FreeSql.DbContext/DbContextOptionsBuilder.cs b/FreeSql.DbContext/DbContextOptionsBuilder.cs new file mode 100644 index 00000000..c8d75785 --- /dev/null +++ b/FreeSql.DbContext/DbContextOptionsBuilder.cs @@ -0,0 +1,17 @@ +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Text; + +namespace FreeSql { + public class DbContextOptionsBuilder { + + internal IFreeSql _fsql; + public DbContextOptionsBuilder UseFreeSql(IFreeSql orm) { + _fsql = orm; + return this; + } + } +} diff --git a/FreeSql.DbContext/DbSet.cs b/FreeSql.DbContext/DbSet.cs new file mode 100644 index 00000000..012ef7ae --- /dev/null +++ b/FreeSql.DbContext/DbSet.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql { + public abstract class DbSet where TEntity : class { + + protected DbContext _ctx; + + public ISelect Select => _ctx._fsql.Select().WithTransaction(_ctx.GetOrBeginTransaction(false)); + + public IInsert Insert(TEntity source) => _ctx._fsql.Insert(source).WithTransaction(_ctx.GetOrBeginTransaction()); + public IInsert Insert(TEntity[] source) => _ctx._fsql.Insert(source).WithTransaction(_ctx.GetOrBeginTransaction()); + public IInsert Insert(IEnumerable source) => _ctx._fsql.Insert(source).WithTransaction(_ctx.GetOrBeginTransaction()); + + public IUpdate Update => _ctx._fsql.Update().WithTransaction(_ctx.GetOrBeginTransaction()); + + public IDelete Delete => _ctx._fsql.Delete().WithTransaction(_ctx.GetOrBeginTransaction()); + } + + internal class BaseDbSet : DbSet where TEntity : class { + + public BaseDbSet(DbContext ctx) { + _ctx = ctx; + } + } +} diff --git a/FreeSql.DbContext/DependencyInjection.cs b/FreeSql.DbContext/DependencyInjection.cs new file mode 100644 index 00000000..41d49cde --- /dev/null +++ b/FreeSql.DbContext/DependencyInjection.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSql { + public static class DbContextDependencyInjection { + + public static IServiceCollection AddFreeDbContext(this IServiceCollection services, Action options) where TDbContext : DbContext { + + services.AddScoped(sp => { + var ctx = Activator.CreateInstance(); + + if (ctx._orm == null) { + var builder = new DbContextOptionsBuilder(); + options(builder); + ctx._orm = builder._fsql; + } + + return ctx; + }); + + return services; + } + } +} diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj new file mode 100644 index 00000000..df3b6775 --- /dev/null +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -0,0 +1,17 @@ + + + + netstandard2.0 + 0.3.19 + true + YeXiangQin + FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. + https://github.com/2881099/FreeSql + FreeSql ORM + + + + + + + diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 5a087470..2a22fd1e 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.3.18 + 0.3.19 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Repository/Repository/BaseRepository.cs b/FreeSql.Repository/Repository/BaseRepository.cs index f6485d21..452d6097 100644 --- a/FreeSql.Repository/Repository/BaseRepository.cs +++ b/FreeSql.Repository/Repository/BaseRepository.cs @@ -94,7 +94,7 @@ namespace FreeSql { public Task UpdateAsync(TEntity entity) => OrmUpdate(entity).ExecuteAffrowsAsync(); protected ISelect OrmSelect(object dywhere) { - var select = _fsql.Select(dywhere).WithTransaction(_unitOfWork?.GetOrBeginTransaction()); + var select = _fsql.Select(dywhere).WithTransaction(_unitOfWork?.GetOrBeginTransaction(false)); var filters = (DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); foreach (var filter in filters) select.Where(filter.Value.Expression); return select.AsTable(AsTableSelect); diff --git a/FreeSql.Repository/UnitOfWork/UnitOfWork.cs b/FreeSql.Repository/UnitOfWork/UnitOfWork.cs index 720ee77e..b7383363 100644 --- a/FreeSql.Repository/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.Repository/UnitOfWork/UnitOfWork.cs @@ -12,8 +12,6 @@ namespace FreeSql { Object _conn; DbTransaction _tran; - bool _isCommitOrRoolback = false; - public UnitOfWork(IFreeSql fsql) { _fsql = fsql; } @@ -23,10 +21,10 @@ namespace FreeSql { _tran = null; _conn = null; } - internal DbTransaction GetOrBeginTransaction() { - _isCommitOrRoolback = false; + internal DbTransaction GetOrBeginTransaction(bool isCreate = true) { if (_tran != null) return _tran; + if (isCreate == false) return null; if (_conn != null) _fsql.Ado.MasterPool.Return(_conn); _conn = _fsql.Ado.MasterPool.Get(); @@ -43,27 +41,22 @@ namespace FreeSql { if (_tran != null) { try { _tran.Commit(); - _isCommitOrRoolback = true; } finally { ReturnObject(); } } } public void Rollback() { - _isCommitOrRoolback = true; if (_tran != null) { try { _tran.Rollback(); - _isCommitOrRoolback = true; } finally { ReturnObject(); } } } public void Dispose() { - if (_isCommitOrRoolback == false) { - this.Commit(); - } + this.Rollback(); } public DefaultRepository GetRepository(Expression> filter = null) where TEntity : class { diff --git a/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests.csproj index 30abb7c1..64c7754f 100644 --- a/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests.csproj @@ -13,6 +13,7 @@ + diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 87688a00..41fabd6c 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -28,10 +28,27 @@ namespace FreeSql.Tests { } ISelect select => g.mysql.Select(); + + + class OrderContext : DbContext { + + public DbSet Orders { get; set; } + public DbSet OrderDetails { get; set; } + } + [Fact] public void Test1() { - var parentSelect1 = select.Where(a => a.Type.Parent.Parent.Parent.Parent.Name == "").Where(b => b.Type.Name == "").ToSql(); + using (var ctx = new OrderContext()) { + ctx.Orders.Insert(new Order { }).ExecuteAffrows(); + ctx.Orders.Delete.Where(a => a.Id > 0).ExecuteAffrows(); + + ctx.OrderDetails.Select.Where(dt => dt.Order.Id == 10).ToList(); + + ctx.SaveChanges(); + } + + var parentSelect1 = select.Where(a => a.Type.Parent.Parent.Parent.Parent.Name == "").Where(b => b.Type.Name == "").ToSql(); var collSelect1 = g.mysql.Select().Where(a => diff --git a/FreeSql.sln b/FreeSql.sln index f1b215f1..15c97332 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -32,6 +32,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "net461_console_01", "Exampl EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "orm_vs", "Examples\orm_vs\orm_vs.csproj", "{1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.DbContext", "FreeSql.DbContext\FreeSql.DbContext.csproj", "{E2D20A95-3045-49BD-973C-0CC6CEB957DB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dbcontext_01", "Examples\dbcontext_01\dbcontext_01.csproj", "{9ED752FF-F908-4611-827A-E99655607567}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -174,6 +178,30 @@ Global {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Release|x64.Build.0 = Release|Any CPU {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Release|x86.ActiveCfg = Release|Any CPU {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Release|x86.Build.0 = Release|Any CPU + {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Debug|x64.ActiveCfg = Debug|Any CPU + {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Debug|x64.Build.0 = Debug|Any CPU + {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Debug|x86.ActiveCfg = Debug|Any CPU + {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Debug|x86.Build.0 = Debug|Any CPU + {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Release|Any CPU.Build.0 = Release|Any CPU + {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Release|x64.ActiveCfg = Release|Any CPU + {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Release|x64.Build.0 = Release|Any CPU + {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Release|x86.ActiveCfg = Release|Any CPU + {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Release|x86.Build.0 = Release|Any CPU + {9ED752FF-F908-4611-827A-E99655607567}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9ED752FF-F908-4611-827A-E99655607567}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9ED752FF-F908-4611-827A-E99655607567}.Debug|x64.ActiveCfg = Debug|Any CPU + {9ED752FF-F908-4611-827A-E99655607567}.Debug|x64.Build.0 = Debug|Any CPU + {9ED752FF-F908-4611-827A-E99655607567}.Debug|x86.ActiveCfg = Debug|Any CPU + {9ED752FF-F908-4611-827A-E99655607567}.Debug|x86.Build.0 = Debug|Any CPU + {9ED752FF-F908-4611-827A-E99655607567}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9ED752FF-F908-4611-827A-E99655607567}.Release|Any CPU.Build.0 = Release|Any CPU + {9ED752FF-F908-4611-827A-E99655607567}.Release|x64.ActiveCfg = Release|Any CPU + {9ED752FF-F908-4611-827A-E99655607567}.Release|x64.Build.0 = Release|Any CPU + {9ED752FF-F908-4611-827A-E99655607567}.Release|x86.ActiveCfg = Release|Any CPU + {9ED752FF-F908-4611-827A-E99655607567}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -185,6 +213,7 @@ Global {A23D0455-CA7B-442D-827E-C4C7E84F9084} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {0637A778-338E-4096-B439-32B18306C75F} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} + {9ED752FF-F908-4611-827A-E99655607567} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 51414c63..48907e4b 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.3.18 + 0.3.19 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index e2589d3c..673e5b5b 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -27,6 +27,7 @@ namespace FreeSql.Internal { if (tbc.TryGetValue(entity, out var trytb)) return trytb; if (common.CodeFirst.GetDbInfo(entity) != null) return null; if (typeof(IEnumerable).IsAssignableFrom(entity)) return null; + if (entity.IsArray) return null; var tbattr = common.GetEntityTableAttribute(entity); trytb = new TableInfo();