mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-06-17 19:43:21 +08:00
拆分 FreeSql 按需引用
This commit is contained in:
parent
37ed28f7a0
commit
f8e897e201
@ -24,7 +24,6 @@ namespace efcore_to_freesql
|
||||
|
||||
Fsql = new FreeSql.FreeSqlBuilder()
|
||||
.UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Pooling=true;Max Pool Size=10")
|
||||
.UseLogger(loggerFactory.CreateLogger<IFreeSql>())
|
||||
.UseAutoSyncStructure(true)
|
||||
.Build();
|
||||
|
||||
@ -69,10 +68,6 @@ namespace efcore_to_freesql
|
||||
|
||||
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();
|
||||
|
||||
|
@ -14,7 +14,6 @@ namespace restful {
|
||||
|
||||
Fsql = new FreeSql.FreeSqlBuilder()
|
||||
.UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10")
|
||||
.UseLogger(loggerFactory.CreateLogger<IFreeSql>())
|
||||
.UseAutoSyncStructure(true)
|
||||
.Build();
|
||||
|
||||
|
@ -0,0 +1,28 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<Version>0.6.1</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 扩展包,可实现【延时加载】属性.</Description>
|
||||
<PackageProjectUrl>https://github.com/2881099/FreeSql</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/2881099/FreeSql</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageTags>FreeSql;ORM</PackageTags>
|
||||
<PackageId>$(AssemblyName)</PackageId>
|
||||
<Title>$(AssemblyName)</Title>
|
||||
<IsPackable>true</IsPackable>
|
||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CS-Script.Core" Version="1.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\FreeSql\FreeSql.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace FreeSql.Extensions.LazyLoading {
|
||||
|
||||
public class LazyLoadingComplier {
|
||||
|
||||
internal static Lazy<CSScriptLib.RoslynEvaluator> _compiler = new Lazy<CSScriptLib.RoslynEvaluator>(() => {
|
||||
//var dlls = Directory.GetFiles(Directory.GetParent(Type.GetType("IFreeSql, FreeSql").Assembly.Location).FullName, "*.dll");
|
||||
var compiler = new CSScriptLib.RoslynEvaluator();
|
||||
compiler.DisableReferencingFromCode = false;
|
||||
//compiler.DebugBuild = true;
|
||||
//foreach (var dll in dlls) {
|
||||
// Console.WriteLine(dll);
|
||||
// var ass = Assembly.LoadFile(dll);
|
||||
// compiler.ReferenceAssembly(ass);
|
||||
//}
|
||||
compiler
|
||||
.ReferenceAssemblyOf<IFreeSql>()
|
||||
.ReferenceDomainAssemblies();
|
||||
return compiler;
|
||||
});
|
||||
|
||||
public static Assembly CompileCode(string cscode) {
|
||||
return _compiler.Value.CompileCode(cscode);
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,13 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Extensions\FreeSql.Extensions.LazyLoading\FreeSql.Extensions.LazyLoading.csproj" />
|
||||
<ProjectReference Include="..\FreeSql\FreeSql.csproj" />
|
||||
<ProjectReference Include="..\Providers\FreeSql.Provider.MySql\FreeSql.Provider.MySql.csproj" />
|
||||
<ProjectReference Include="..\Providers\FreeSql.Provider.Oracle\FreeSql.Provider.Oracle.csproj" />
|
||||
<ProjectReference Include="..\Providers\FreeSql.Provider.PostgreSQL\FreeSql.Provider.PostgreSQL.csproj" />
|
||||
<ProjectReference Include="..\Providers\FreeSql.Provider.Sqlite\FreeSql.Provider.Sqlite.csproj" />
|
||||
<ProjectReference Include="..\Providers\FreeSql.Provider.SqlServer\FreeSql.Provider.SqlServer.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
@ -8,32 +7,27 @@ public class g {
|
||||
|
||||
public static IFreeSql mysql = new FreeSql.FreeSqlBuilder()
|
||||
.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=100")
|
||||
.UseLogger(new LoggerFactory().CreateLogger("FreeSql.MySql"))
|
||||
.UseAutoSyncStructure(false)
|
||||
.Build();
|
||||
|
||||
//public static IFreeSql sqlserver = new FreeSql.FreeSqlBuilder()
|
||||
// .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=cms;Pooling=true;Max Pool Size=10")
|
||||
// .UseLogger(new LoggerFactory().CreateLogger("FreeSql.SqlServer"))
|
||||
// .UseAutoSyncStructure(false)
|
||||
// .Build();
|
||||
|
||||
//public static IFreeSql pgsql = new FreeSql.FreeSqlBuilder()
|
||||
// .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10")
|
||||
// .UseLogger(new LoggerFactory().CreateLogger("FreeSql.PostgreSQL"))
|
||||
// .UseAutoSyncStructure(false)
|
||||
// .UseSyncStructureToLower(true)
|
||||
// .Build();
|
||||
|
||||
//public static IFreeSql oracle = new FreeSql.FreeSqlBuilder()
|
||||
// .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10")
|
||||
// .UseLogger(new LoggerFactory().CreateLogger("FreeSql.Oracle"))
|
||||
// .UseAutoSyncStructure(false)
|
||||
// .Build();
|
||||
|
||||
//public static IFreeSql sqlite = new FreeSql.FreeSqlBuilder()
|
||||
// .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10")
|
||||
// .UseLogger(new LoggerFactory().CreateLogger("FreeSql.Sqlite"))
|
||||
// .UseAutoSyncStructure(false)
|
||||
// .Build();
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FreeSql.DbContext" Version="0.5.19" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.8" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.0" />
|
||||
@ -15,7 +14,14 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\FreeSql.DbContext\FreeSql.DbContext\FreeSql.DbContext.csproj" />
|
||||
<ProjectReference Include="..\Extensions\FreeSql.Extensions.LazyLoading\FreeSql.Extensions.LazyLoading.csproj" />
|
||||
<ProjectReference Include="..\FreeSql\FreeSql.csproj" />
|
||||
<ProjectReference Include="..\Providers\FreeSql.Provider.MySql\FreeSql.Provider.MySql.csproj" />
|
||||
<ProjectReference Include="..\Providers\FreeSql.Provider.Oracle\FreeSql.Provider.Oracle.csproj" />
|
||||
<ProjectReference Include="..\Providers\FreeSql.Provider.PostgreSQL\FreeSql.Provider.PostgreSQL.csproj" />
|
||||
<ProjectReference Include="..\Providers\FreeSql.Provider.Sqlite\FreeSql.Provider.Sqlite.csproj" />
|
||||
<ProjectReference Include="..\Providers\FreeSql.Provider.SqlServer\FreeSql.Provider.SqlServer.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,27 +0,0 @@
|
||||
using FreeSql.DataAnnotations;
|
||||
using FreeSql.Generator;
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace FreeSql.Tests.Generator {
|
||||
public class MySqlTemplateGeneratorTest {
|
||||
|
||||
[Fact]
|
||||
public void BuildSimpleEntity() {
|
||||
var gen = new TemplateGenerator();
|
||||
gen.Build(g.mysql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", @"C:\Users\28810\Desktop\新建文件夹 (9)", "cccddd");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildSimpleEntityNavigationObject () {
|
||||
var gen = new TemplateGenerator();
|
||||
gen.Build(g.mysql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "cccddd");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildRichEntityNavigationObject() {
|
||||
var gen = new TemplateGenerator();
|
||||
gen.Build(g.mysql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\rich-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "cccddd");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
using FreeSql.DataAnnotations;
|
||||
using FreeSql.Generator;
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace FreeSql.Tests.Generator {
|
||||
public class PostgreSQLTemplateGeneratorTest {
|
||||
|
||||
[Fact]
|
||||
public void BuildSimpleEntity() {
|
||||
var gen = new TemplateGenerator();
|
||||
gen.Build(g.pgsql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\PostgreSQL\simple-entity", @"C:\Users\28810\Desktop\新建文件夹 (9)", "tedb");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildSimpleEntityNavigationObject () {
|
||||
var gen = new TemplateGenerator();
|
||||
gen.Build(g.pgsql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\PostgreSQL\simple-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "tedb");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildRichEntityNavigationObject() {
|
||||
var gen = new TemplateGenerator();
|
||||
gen.Build(g.pgsql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\PostgreSQL\rich-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "tedb");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using FreeSql.DataAnnotations;
|
||||
using FreeSql.Generator;
|
||||
using FreeSql.Tests.DataContext.SqlServer;
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace FreeSql.Tests.Generator {
|
||||
|
||||
[Collection("SqlServerCollection")]
|
||||
public class SqlServerTemplateGeneratorTest {
|
||||
SqlServerFixture _sqlserverFixture;
|
||||
|
||||
public SqlServerTemplateGeneratorTest(SqlServerFixture sqlserverFixture)
|
||||
{
|
||||
_sqlserverFixture = sqlserverFixture;
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void BuildSimpleEntity() {
|
||||
var gen = new TemplateGenerator();
|
||||
gen.Build(_sqlserverFixture.SqlServer.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\SqlServer\simple-entity", @"C:\Users\28810\Desktop\新建文件夹 (9)", "shop");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildSimpleEntityNavigationObject () {
|
||||
var gen = new TemplateGenerator();
|
||||
gen.Build(_sqlserverFixture.SqlServer.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\SqlServer\simple-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "shop");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildRichEntityNavigationObject() {
|
||||
var gen = new TemplateGenerator();
|
||||
gen.Build(_sqlserverFixture.SqlServer.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\SqlServer\rich-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "shop");
|
||||
}
|
||||
}
|
||||
}
|
@ -230,8 +230,8 @@ namespace FreeSql.Tests.MySql {
|
||||
|
||||
});
|
||||
|
||||
var t100 = g.mysql.Select<TestInfo>().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).Caching(50).ToList();
|
||||
var t101 = g.mysql.Select<TestInfo>().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).Caching(50).ToList();
|
||||
var t100 = g.mysql.Select<TestInfo>().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList();
|
||||
var t101 = g.mysql.Select<TestInfo>().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList();
|
||||
|
||||
|
||||
var t1111 = g.mysql.Select<TestInfo>().ToList(a => new { a.Id, a.Title, a.Type });
|
||||
@ -304,16 +304,6 @@ namespace FreeSql.Tests.MySql {
|
||||
Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql());
|
||||
}
|
||||
[Fact]
|
||||
public void Caching() {
|
||||
var result1 = select.Where(a => 1 == 1).Caching(20, "testcaching").ToList();
|
||||
var testcaching1 = g.mysql.Cache.Get("testcaching");
|
||||
Assert.NotNull(testcaching1);
|
||||
var result2 = select.Where(a => 1 == 1).Caching(20, "testcaching").ToList();
|
||||
var testcaching2 = g.mysql.Cache.Get("testcaching");
|
||||
Assert.NotNull(testcaching2);
|
||||
Assert.Equal(result1.Count, result1.Count);
|
||||
}
|
||||
[Fact]
|
||||
public void From() {
|
||||
var query2 = select.From<TestTypeInfo>((s, b) => s
|
||||
.LeftJoin(a => a.TypeGuid == b.Guid)
|
||||
|
@ -385,27 +385,11 @@ namespace FreeSql.Tests.MySql {
|
||||
internal static IFreeSql mysql => null;
|
||||
public static FreeSql.ISelect<Tb_alltype> Select => mysql.Select<Tb_alltype>();
|
||||
|
||||
public static int ItemCacheTimeout = 180;
|
||||
public static Tb_alltype GetItem(int Id) => Select.Where(a => a.Id == Id).Caching(ItemCacheTimeout, string.Concat("test:tb_alltype:", Id)).ToOne();
|
||||
|
||||
public static long Delete(int Id) {
|
||||
var affrows = mysql.Delete<Tb_alltype>().Where(a => a.Id == Id).ExecuteAffrows();
|
||||
if (ItemCacheTimeout > 0) RemoveCache(new Tb_alltype { Id = Id });
|
||||
return affrows;
|
||||
}
|
||||
|
||||
internal static void RemoveCache(Tb_alltype item) => RemoveCache(item == null ? null : new[] { item });
|
||||
internal static void RemoveCache(IEnumerable<Tb_alltype> items) {
|
||||
if (ItemCacheTimeout <= 0 || items == null || items.Any() == false) return;
|
||||
var keys = new string[items.Count() * 1];
|
||||
var keysIdx = 0;
|
||||
foreach (var item in items) {
|
||||
keys[keysIdx++] = string.Concat("test:tb_alltype:", item.Id);
|
||||
}
|
||||
if (mysql.Ado.TransactionCurrentThread != null) mysql.Ado.TransactionPreRemoveCache(keys);
|
||||
else mysql.Cache.Remove(keys);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert
|
||||
/// </summary>
|
||||
|
@ -199,16 +199,6 @@ namespace FreeSql.Tests.Oracle {
|
||||
Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql());
|
||||
}
|
||||
[Fact]
|
||||
public void Caching() {
|
||||
var result1 = select.Where(a => 1 == 1).Caching(20, "testcaching").ToList();
|
||||
var testcaching1 = g.oracle.Cache.Get("testcaching");
|
||||
Assert.NotNull(testcaching1);
|
||||
var result2 = select.Where(a => 1 == 1).Caching(20, "testcaching").ToList();
|
||||
var testcaching2 = g.oracle.Cache.Get("testcaching");
|
||||
Assert.NotNull(testcaching2);
|
||||
Assert.Equal(result1.Count, result1.Count);
|
||||
}
|
||||
[Fact]
|
||||
public void From() {
|
||||
var query2 = select.From<TestTypeInfo>((s, b) => s
|
||||
.LeftJoin(a => a.TypeGuid == b.Guid)
|
||||
|
@ -208,8 +208,8 @@ namespace FreeSql.Tests.PostgreSQL {
|
||||
|
||||
});
|
||||
|
||||
var t100 = g.pgsql.Select<TestInfo>().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).Caching(50).ToList();
|
||||
var t101 = g.pgsql.Select<TestInfo>().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).Caching(50).ToList();
|
||||
var t100 = g.pgsql.Select<TestInfo>().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList();
|
||||
var t101 = g.pgsql.Select<TestInfo>().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList();
|
||||
|
||||
|
||||
var t1111 = g.pgsql.Select<TestInfo>().ToList(a => new { a.Id, a.Title, a.Type });
|
||||
@ -268,16 +268,7 @@ namespace FreeSql.Tests.PostgreSQL {
|
||||
public void Master() {
|
||||
Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql());
|
||||
}
|
||||
[Fact]
|
||||
public void Caching() {
|
||||
var result1 = select.Where(a => 1 == 1).Caching(20, "testcaching").ToList();
|
||||
var testcaching1 = g.pgsql.Cache.Get("testcaching");
|
||||
Assert.NotNull(testcaching1);
|
||||
var result2 = select.Where(a => 1 == 1).Caching(20, "testcaching").ToList();
|
||||
var testcaching2 = g.pgsql.Cache.Get("testcaching");
|
||||
Assert.NotNull(testcaching2);
|
||||
Assert.Equal(result1.Count, result1.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void From() {
|
||||
|
||||
|
@ -200,16 +200,7 @@ namespace FreeSql.Tests.SqlServer {
|
||||
public void Master() {
|
||||
Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql());
|
||||
}
|
||||
[Fact]
|
||||
public void Caching() {
|
||||
var result1 = select.Where(a => 1 == 1).Caching(20, "testcaching").ToList();
|
||||
var testcaching1 = _sqlserverFixture.SqlServer.Cache.Get("testcaching");
|
||||
Assert.NotNull(testcaching1);
|
||||
var result2 = select.Where(a => 1 == 1).Caching(20, "testcaching").ToList();
|
||||
var testcaching2 = _sqlserverFixture.SqlServer.Cache.Get("testcaching");
|
||||
Assert.NotNull(testcaching2);
|
||||
Assert.Equal(result1.Count, result1.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void From() {
|
||||
var query2 = select.From<TestTypeInfo>((s, b) => s
|
||||
|
@ -210,16 +210,6 @@ namespace FreeSql.Tests.Sqlite {
|
||||
Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql());
|
||||
}
|
||||
[Fact]
|
||||
public void Caching() {
|
||||
var result1 = select.Where(a => 1 == 1).Caching(20, "testcaching").ToList();
|
||||
var testcaching1 = g.sqlite.Cache.Get("testcaching");
|
||||
Assert.NotNull(testcaching1);
|
||||
var result2 = select.Where(a => 1 == 1).Caching(20, "testcaching").ToList();
|
||||
var testcaching2 = g.sqlite.Cache.Get("testcaching");
|
||||
Assert.NotNull(testcaching2);
|
||||
Assert.Equal(result1.Count, result1.Count);
|
||||
}
|
||||
[Fact]
|
||||
public void From() {
|
||||
var query2 = select.From<TestTypeInfo>((s, b) => s
|
||||
.LeftJoin(a => a.TypeGuid == b.Guid)
|
||||
|
@ -508,8 +508,8 @@ namespace FreeSql.Tests {
|
||||
|
||||
});
|
||||
|
||||
var t100 = g.mysql.Select<TestInfo>().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).Caching(50).ToList();
|
||||
var t101 = g.mysql.Select<TestInfo>().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).Caching(50).ToList();
|
||||
var t100 = g.mysql.Select<TestInfo>().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList();
|
||||
var t101 = g.mysql.Select<TestInfo>().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList();
|
||||
|
||||
|
||||
var t1111 = g.mysql.Select<TestInfo>().ToList(a => new { a.Id, a.Title, a.Type });
|
||||
|
122
FreeSql.sln
122
FreeSql.sln
@ -24,6 +24,26 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "orm_vs", "Examples\orm_vs\o
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "benchmarker", "Examples\benchmarker\benchmarker.csproj", "{E7405816-F32A-4F3E-AD76-29129962C6AA}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Providers", "Providers", "{2A381C57-2697-427B-9F10-55DA11FD02E4}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.MySql", "Providers\FreeSql.Provider.MySql\FreeSql.Provider.MySql.csproj", "{28C6A39C-7AE7-4210-B7B0-0970216637A8}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.Oracle", "Providers\FreeSql.Provider.Oracle\FreeSql.Provider.Oracle.csproj", "{3DE45286-B0DB-4D74-B322-F5467FB2EF53}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Provider.Sqlite", "Providers\FreeSql.Provider.Sqlite\FreeSql.Provider.Sqlite.csproj", "{559B6369-1868-4A06-A590-F80BA7B80A1B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Provider.SqlServer", "Providers\FreeSql.Provider.SqlServer\FreeSql.Provider.SqlServer.csproj", "{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Provider.PostgreSQL", "Providers\FreeSql.Provider.PostgreSQL\FreeSql.Provider.PostgreSQL.csproj", "{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{4A92E8A6-9A6D-41A1-9CDA-DE10899648AA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Extensions.LazyLoading", "Extensions\FreeSql.Extensions.LazyLoading\FreeSql.Extensions.LazyLoading.csproj", "{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.DbContext", "..\FreeSql.DbContext\FreeSql.DbContext\FreeSql.DbContext.csproj", "{84BA8C1A-A432-4D03-A2FA-127B8776C872}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Repository", "..\FreeSql.DbContext\FreeSql.Repository\FreeSql.Repository.csproj", "{8B92F97B-02FC-4FA0-8FA5-F494CAF15336}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -118,6 +138,102 @@ Global
|
||||
{E7405816-F32A-4F3E-AD76-29129962C6AA}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E7405816-F32A-4F3E-AD76-29129962C6AA}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E7405816-F32A-4F3E-AD76-29129962C6AA}.Release|x86.Build.0 = Release|Any CPU
|
||||
{28C6A39C-7AE7-4210-B7B0-0970216637A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{28C6A39C-7AE7-4210-B7B0-0970216637A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{28C6A39C-7AE7-4210-B7B0-0970216637A8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{28C6A39C-7AE7-4210-B7B0-0970216637A8}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{28C6A39C-7AE7-4210-B7B0-0970216637A8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{28C6A39C-7AE7-4210-B7B0-0970216637A8}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{28C6A39C-7AE7-4210-B7B0-0970216637A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{28C6A39C-7AE7-4210-B7B0-0970216637A8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{28C6A39C-7AE7-4210-B7B0-0970216637A8}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{28C6A39C-7AE7-4210-B7B0-0970216637A8}.Release|x64.Build.0 = Release|Any CPU
|
||||
{28C6A39C-7AE7-4210-B7B0-0970216637A8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{28C6A39C-7AE7-4210-B7B0-0970216637A8}.Release|x86.Build.0 = Release|Any CPU
|
||||
{3DE45286-B0DB-4D74-B322-F5467FB2EF53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3DE45286-B0DB-4D74-B322-F5467FB2EF53}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3DE45286-B0DB-4D74-B322-F5467FB2EF53}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{3DE45286-B0DB-4D74-B322-F5467FB2EF53}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{3DE45286-B0DB-4D74-B322-F5467FB2EF53}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{3DE45286-B0DB-4D74-B322-F5467FB2EF53}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{3DE45286-B0DB-4D74-B322-F5467FB2EF53}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3DE45286-B0DB-4D74-B322-F5467FB2EF53}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3DE45286-B0DB-4D74-B322-F5467FB2EF53}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{3DE45286-B0DB-4D74-B322-F5467FB2EF53}.Release|x64.Build.0 = Release|Any CPU
|
||||
{3DE45286-B0DB-4D74-B322-F5467FB2EF53}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{3DE45286-B0DB-4D74-B322-F5467FB2EF53}.Release|x86.Build.0 = Release|Any CPU
|
||||
{559B6369-1868-4A06-A590-F80BA7B80A1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{559B6369-1868-4A06-A590-F80BA7B80A1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{559B6369-1868-4A06-A590-F80BA7B80A1B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{559B6369-1868-4A06-A590-F80BA7B80A1B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{559B6369-1868-4A06-A590-F80BA7B80A1B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{559B6369-1868-4A06-A590-F80BA7B80A1B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{559B6369-1868-4A06-A590-F80BA7B80A1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{559B6369-1868-4A06-A590-F80BA7B80A1B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{559B6369-1868-4A06-A590-F80BA7B80A1B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{559B6369-1868-4A06-A590-F80BA7B80A1B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{559B6369-1868-4A06-A590-F80BA7B80A1B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{559B6369-1868-4A06-A590-F80BA7B80A1B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}.Release|x64.Build.0 = Release|Any CPU
|
||||
{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE}.Release|x86.Build.0 = Release|Any CPU
|
||||
{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}.Release|x64.Build.0 = Release|Any CPU
|
||||
{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2}.Release|x86.Build.0 = Release|Any CPU
|
||||
{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Release|x64.Build.0 = Release|Any CPU
|
||||
{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9}.Release|x86.Build.0 = Release|Any CPU
|
||||
{84BA8C1A-A432-4D03-A2FA-127B8776C872}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{84BA8C1A-A432-4D03-A2FA-127B8776C872}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{84BA8C1A-A432-4D03-A2FA-127B8776C872}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{84BA8C1A-A432-4D03-A2FA-127B8776C872}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{84BA8C1A-A432-4D03-A2FA-127B8776C872}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{84BA8C1A-A432-4D03-A2FA-127B8776C872}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{84BA8C1A-A432-4D03-A2FA-127B8776C872}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{84BA8C1A-A432-4D03-A2FA-127B8776C872}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{84BA8C1A-A432-4D03-A2FA-127B8776C872}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{84BA8C1A-A432-4D03-A2FA-127B8776C872}.Release|x64.Build.0 = Release|Any CPU
|
||||
{84BA8C1A-A432-4D03-A2FA-127B8776C872}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{84BA8C1A-A432-4D03-A2FA-127B8776C872}.Release|x86.Build.0 = Release|Any CPU
|
||||
{8B92F97B-02FC-4FA0-8FA5-F494CAF15336}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8B92F97B-02FC-4FA0-8FA5-F494CAF15336}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8B92F97B-02FC-4FA0-8FA5-F494CAF15336}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{8B92F97B-02FC-4FA0-8FA5-F494CAF15336}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{8B92F97B-02FC-4FA0-8FA5-F494CAF15336}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8B92F97B-02FC-4FA0-8FA5-F494CAF15336}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{8B92F97B-02FC-4FA0-8FA5-F494CAF15336}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8B92F97B-02FC-4FA0-8FA5-F494CAF15336}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8B92F97B-02FC-4FA0-8FA5-F494CAF15336}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{8B92F97B-02FC-4FA0-8FA5-F494CAF15336}.Release|x64.Build.0 = Release|Any CPU
|
||||
{8B92F97B-02FC-4FA0-8FA5-F494CAF15336}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8B92F97B-02FC-4FA0-8FA5-F494CAF15336}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -127,6 +243,12 @@ Global
|
||||
{B93981B8-3295-4EDD-B314-BCA77B6BF37A} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B}
|
||||
{1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B}
|
||||
{E7405816-F32A-4F3E-AD76-29129962C6AA} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B}
|
||||
{28C6A39C-7AE7-4210-B7B0-0970216637A8} = {2A381C57-2697-427B-9F10-55DA11FD02E4}
|
||||
{3DE45286-B0DB-4D74-B322-F5467FB2EF53} = {2A381C57-2697-427B-9F10-55DA11FD02E4}
|
||||
{559B6369-1868-4A06-A590-F80BA7B80A1B} = {2A381C57-2697-427B-9F10-55DA11FD02E4}
|
||||
{B61AAC9E-59E9-4F47-BBE3-97AC24112EFE} = {2A381C57-2697-427B-9F10-55DA11FD02E4}
|
||||
{22C0B061-F7CC-4A7F-AEC7-D4DBBE6B23B2} = {2A381C57-2697-427B-9F10-55DA11FD02E4}
|
||||
{1FE00D5E-EC0F-4238-93EC-DABA26DBD1A9} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98}
|
||||
|
@ -66,7 +66,7 @@ namespace FreeSql.DataAnnotations {
|
||||
/// <summary>
|
||||
/// 数据库默认值
|
||||
/// </summary>
|
||||
internal object DbDefautValue { get; set; }
|
||||
public object DbDefautValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型映射,比如:可将 enum 属性映射成 typeof(string)
|
||||
|
@ -5,46 +5,46 @@ namespace FreeSql.DatabaseModel {
|
||||
/// <summary>
|
||||
/// 所属表
|
||||
/// </summary>
|
||||
public DbTableInfo Table { get; internal set; }
|
||||
public DbTableInfo Table { get; set; }
|
||||
/// <summary>
|
||||
/// 列名
|
||||
/// </summary>
|
||||
public string Name { get; internal set; }
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// 映射到 C# 类型
|
||||
/// </summary>
|
||||
public Type CsType { get; internal set; }
|
||||
public Type CsType { get; set; }
|
||||
/// <summary>
|
||||
/// 数据库枚举类型int值
|
||||
/// </summary>
|
||||
public int DbType { get; internal set; }
|
||||
public int DbType { get; set; }
|
||||
/// <summary>
|
||||
/// 数据库类型,字符串,varchar
|
||||
/// </summary>
|
||||
public string DbTypeText { get; internal set; }
|
||||
public string DbTypeText { get; set; }
|
||||
/// <summary>
|
||||
/// 数据库类型,字符串,varchar(255)
|
||||
/// </summary>
|
||||
public string DbTypeTextFull { get; internal set; }
|
||||
public string DbTypeTextFull { get; set; }
|
||||
/// <summary>
|
||||
/// 最大长度
|
||||
/// </summary>
|
||||
public int MaxLength { get; internal set; }
|
||||
public int MaxLength { get; set; }
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
public bool IsPrimary { get; internal set; }
|
||||
public bool IsPrimary { get; set; }
|
||||
/// <summary>
|
||||
/// 自增标识
|
||||
/// </summary>
|
||||
public bool IsIdentity { get; internal set; }
|
||||
public bool IsIdentity { get; set; }
|
||||
/// <summary>
|
||||
/// 是否可DBNull
|
||||
/// </summary>
|
||||
public bool IsNullable { get; internal set; }
|
||||
public bool IsNullable { get; set; }
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Coment { get; internal set; }
|
||||
public string Coment { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -6,19 +6,19 @@ namespace FreeSql.DatabaseModel {
|
||||
/// <summary>
|
||||
/// 唯一标识
|
||||
/// </summary>
|
||||
public string Id { get; internal set; }
|
||||
public string Id { get; set; }
|
||||
/// <summary>
|
||||
/// SqlServer下是Owner、PostgreSQL下是Schema、MySql下是数据库名
|
||||
/// </summary>
|
||||
public string Schema { get; internal set; }
|
||||
public string Schema { get; set; }
|
||||
/// <summary>
|
||||
/// 表名
|
||||
/// </summary>
|
||||
public string Name { get; internal set; }
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// 表备注,SqlServer下是扩展属性 MS_Description
|
||||
/// </summary>
|
||||
public string Comment { get; internal set; }
|
||||
public string Comment { get; set; }
|
||||
/// <summary>
|
||||
/// 表/视图
|
||||
/// </summary>
|
||||
@ -26,27 +26,27 @@ namespace FreeSql.DatabaseModel {
|
||||
/// <summary>
|
||||
/// 列
|
||||
/// </summary>
|
||||
public List<DbColumnInfo> Columns { get; internal set; } = new List<DbColumnInfo>();
|
||||
public List<DbColumnInfo> Columns { get; set; } = new List<DbColumnInfo>();
|
||||
/// <summary>
|
||||
/// 自增列
|
||||
/// </summary>
|
||||
public List<DbColumnInfo> Identitys { get; internal set; } = new List<DbColumnInfo>();
|
||||
public List<DbColumnInfo> Identitys { get; set; } = new List<DbColumnInfo>();
|
||||
/// <summary>
|
||||
/// 主键/组合
|
||||
/// </summary>
|
||||
public List<DbColumnInfo> Primarys { get; internal set; } = new List<DbColumnInfo>();
|
||||
public List<DbColumnInfo> Primarys { get; set; } = new List<DbColumnInfo>();
|
||||
/// <summary>
|
||||
/// 唯一键/组合
|
||||
/// </summary>
|
||||
public Dictionary<string, List<DbColumnInfo>> UniquesDict { get; internal set; } = new Dictionary<string, List<DbColumnInfo>>();
|
||||
public Dictionary<string, List<DbColumnInfo>> UniquesDict { get; set; } = new Dictionary<string, List<DbColumnInfo>>();
|
||||
/// <summary>
|
||||
/// 索引/组合
|
||||
/// </summary>
|
||||
public Dictionary<string, List<DbColumnInfo>> IndexesDict { get; internal set; } = new Dictionary<string, List<DbColumnInfo>>();
|
||||
public Dictionary<string, List<DbColumnInfo>> IndexesDict { get; set; } = new Dictionary<string, List<DbColumnInfo>>();
|
||||
/// <summary>
|
||||
/// 外键
|
||||
/// </summary>
|
||||
public Dictionary<string, DbForeignInfo> ForeignsDict { get; internal set; } = new Dictionary<string, DbForeignInfo>();
|
||||
public Dictionary<string, DbForeignInfo> ForeignsDict { get; set; } = new Dictionary<string, DbForeignInfo>();
|
||||
|
||||
public List<List<DbColumnInfo>> Uniques => UniquesDict.Values.ToList();
|
||||
public List<List<DbColumnInfo>> Indexes => IndexesDict.Values.ToList();
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
namespace FreeSql.DatabaseModel {
|
||||
public class DbForeignInfo {
|
||||
public DbTableInfo Table { get; internal set; }
|
||||
public List<DbColumnInfo> Columns { get; internal set; } = new List<DbColumnInfo>();
|
||||
public DbTableInfo ReferencedTable { get; internal set; }
|
||||
public List<DbColumnInfo> ReferencedColumns { get; internal set; } = new List<DbColumnInfo>();
|
||||
public DbTableInfo Table { get; set; }
|
||||
public List<DbColumnInfo> Columns { get; set; } = new List<DbColumnInfo>();
|
||||
public DbTableInfo ReferencedTable { get; set; }
|
||||
public List<DbColumnInfo> ReferencedColumns { get; set; } = new List<DbColumnInfo>();
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ public static partial class FreeSqlGlobalExtensions {
|
||||
public static bool IsNumberType(this Type that) => that == null ? false : dicIsNumberType.Value.ContainsKey(that);
|
||||
public static bool IsNullableType(this Type that) => that?.FullName.StartsWith("System.Nullable`1[") == true;
|
||||
public static bool IsAnonymousType(this Type that) => that?.FullName.StartsWith("<>f__AnonymousType") == true;
|
||||
internal static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GenericTypeArguments.First() : that;
|
||||
public static Type NullableTypeOrThis(this Type that) => that?.IsNullableType() == true ? that.GenericTypeArguments.First() : that;
|
||||
|
||||
/// <summary>
|
||||
/// 测量两个经纬度的距离,返回单位:米
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<Version>0.5.23</Version>
|
||||
<Version>0.6.1</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>
|
||||
@ -23,18 +23,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CS-Script.Core" Version="1.0.6" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.1.0" />
|
||||
<PackageReference Include="MySql.Data" Version="8.0.15" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||
<PackageReference Include="Npgsql.LegacyPostgis" Version="4.0.5" />
|
||||
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="2.18.5" />
|
||||
<PackageReference Include="SafeObjectPool" Version="2.0.1" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
|
||||
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.110" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -409,20 +409,6 @@
|
||||
<param name="columnType"></param>
|
||||
<param name="setExp"></param>
|
||||
</member>
|
||||
<member name="M:FreeSql.FreeSqlBuilder.UseCache(Microsoft.Extensions.Caching.Distributed.IDistributedCache)">
|
||||
<summary>
|
||||
使用缓存,不指定默认使用内存
|
||||
</summary>
|
||||
<param name="cache">缓存实现</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.FreeSqlBuilder.UseLogger(Microsoft.Extensions.Logging.ILogger)">
|
||||
<summary>
|
||||
使用日志,不指定默认输出控制台
|
||||
</summary>
|
||||
<param name="logger"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.FreeSqlBuilder.UseConnectionString(FreeSql.DataType,System.String)">
|
||||
<summary>
|
||||
使用连接串
|
||||
@ -488,16 +474,6 @@
|
||||
<param name="executed">执行后,可监视执行性能</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.Generator.TemplateEngin.ITemplateOutput.OuTpUt(System.Text.StringBuilder,System.Collections.IDictionary,System.String,FreeSql.Generator.TemplateEngin)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="tOuTpUt">返回内容</param>
|
||||
<param name="oPtIoNs">渲染对象</param>
|
||||
<param name="rEfErErFiLeNaMe">当前文件路径</param>
|
||||
<param name="tEmPlAtEsEnDeR"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.IDelete`1.WithTransaction(System.Data.Common.DbTransaction)">
|
||||
<summary>
|
||||
指定事务对象
|
||||
@ -807,14 +783,6 @@
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.ISelect0`2.Caching(System.Int32,System.String)">
|
||||
<summary>
|
||||
缓存查询结果
|
||||
</summary>
|
||||
<param name="seconds">缓存秒数</param>
|
||||
<param name="key">缓存key</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.ISelect0`2.LeftJoin(System.Linq.Expressions.Expression{System.Func{`1,System.Boolean}})">
|
||||
<summary>
|
||||
左联查询,使用导航属性自动生成SQL
|
||||
@ -1643,12 +1611,6 @@
|
||||
当前线程的事务
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:FreeSql.IAdo.TransactionPreRemoveCache(System.String[])">
|
||||
<summary>
|
||||
事务完成前预删除缓存
|
||||
</summary>
|
||||
<param name="keys"></param>
|
||||
</member>
|
||||
<member name="M:FreeSql.IAdo.ExecuteReader(System.Action{System.Data.Common.DbDataReader},System.Data.CommandType,System.String,System.Data.Common.DbParameter[])">
|
||||
<summary>
|
||||
查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
|
||||
@ -2081,118 +2043,6 @@
|
||||
耗时(单位:毫秒)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:FreeSql.ICache.Serialize">
|
||||
<summary>
|
||||
缓存数据时序列化方法,若无设置则默认使用 Json.net
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:FreeSql.ICache.Deserialize">
|
||||
<summary>
|
||||
获取缓存数据时反序列化方法,若无设置则默认使用 Json.net
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:FreeSql.ICache.Set``1(System.String,``0,System.Int32)">
|
||||
<summary>
|
||||
缓存可序列化数据
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="key">缓存键</param>
|
||||
<param name="data">可序列化数据</param>
|
||||
<param name="timeoutSeconds">缓存秒数,<=0时永久缓存</param>
|
||||
</member>
|
||||
<member name="M:FreeSql.ICache.Get``1(System.String)">
|
||||
<summary>
|
||||
循环或批量获取缓存数据
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="key"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.ICache.Get(System.String)">
|
||||
<summary>
|
||||
循环或批量获取缓存数据
|
||||
</summary>
|
||||
<param name="key"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.ICache.Remove(System.String[])">
|
||||
<summary>
|
||||
循环或批量删除缓存键
|
||||
</summary>
|
||||
<param name="keys">缓存键[数组]</param>
|
||||
</member>
|
||||
<member name="M:FreeSql.ICache.Shell``1(System.String,System.Int32,System.Func{``0})">
|
||||
<summary>
|
||||
缓存壳
|
||||
</summary>
|
||||
<typeparam name="T">缓存类型</typeparam>
|
||||
<param name="key">缓存键</param>
|
||||
<param name="timeoutSeconds">缓存秒数</param>
|
||||
<param name="getData">获取源数据的函数</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.ICache.Shell``1(System.String,System.String,System.Int32,System.Func{``0})">
|
||||
<summary>
|
||||
缓存壳(哈希表)
|
||||
</summary>
|
||||
<typeparam name="T">缓存类型</typeparam>
|
||||
<param name="key">缓存键</param>
|
||||
<param name="field">字段</param>
|
||||
<param name="timeoutSeconds">缓存秒数</param>
|
||||
<param name="getData">获取源数据的函数</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.ICache.SetAsync``1(System.String,``0,System.Int32)">
|
||||
<summary>
|
||||
缓存可序列化数据
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="key">缓存键</param>
|
||||
<param name="data">可序列化数据</param>
|
||||
<param name="timeoutSeconds">缓存秒数,<=0时永久缓存</param>
|
||||
</member>
|
||||
<member name="M:FreeSql.ICache.GetAsync``1(System.String)">
|
||||
<summary>
|
||||
循环或批量获取缓存数据
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="key"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.ICache.GetAsync(System.String)">
|
||||
<summary>
|
||||
循环或批量获取缓存数据
|
||||
</summary>
|
||||
<param name="key"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.ICache.RemoveAsync(System.String[])">
|
||||
<summary>
|
||||
循环或批量删除缓存键
|
||||
</summary>
|
||||
<param name="keys">缓存键[数组]</param>
|
||||
</member>
|
||||
<member name="M:FreeSql.ICache.ShellAsync``1(System.String,System.Int32,System.Func{System.Threading.Tasks.Task{``0}})">
|
||||
<summary>
|
||||
缓存壳
|
||||
</summary>
|
||||
<typeparam name="T">缓存类型</typeparam>
|
||||
<param name="key">缓存键</param>
|
||||
<param name="timeoutSeconds">缓存秒数</param>
|
||||
<param name="getDataAsync">获取源数据的函数</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSql.ICache.ShellAsync``1(System.String,System.String,System.Int32,System.Func{System.Threading.Tasks.Task{``0}})">
|
||||
<summary>
|
||||
缓存壳(哈希表)
|
||||
</summary>
|
||||
<typeparam name="T">缓存类型</typeparam>
|
||||
<param name="key">缓存键</param>
|
||||
<param name="field">字段</param>
|
||||
<param name="timeoutSeconds">缓存秒数</param>
|
||||
<param name="getDataAsync">获取源数据的函数</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="P:FreeSql.ICodeFirst.IsAutoSyncStructure">
|
||||
<summary>
|
||||
【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改
|
||||
@ -2385,46 +2235,6 @@
|
||||
<param name="that"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSqlGlobalExtensions.FormatMySql(System.String,System.Object[])">
|
||||
<summary>
|
||||
特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
|
||||
</summary>
|
||||
<param name="that"></param>
|
||||
<param name="args"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSqlGlobalExtensions.FormatOracleSQL(System.String,System.Object[])">
|
||||
<summary>
|
||||
特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
|
||||
</summary>
|
||||
<param name="that"></param>
|
||||
<param name="args"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSqlGlobalExtensions.FormatPostgreSQL(System.String,System.Object[])">
|
||||
<summary>
|
||||
特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
|
||||
</summary>
|
||||
<param name="that"></param>
|
||||
<param name="args"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSqlGlobalExtensions.FormatSqlite(System.String,System.Object[])">
|
||||
<summary>
|
||||
特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
|
||||
</summary>
|
||||
<param name="that"></param>
|
||||
<param name="args"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeSqlGlobalExtensions.FormatSqlServer(System.String,System.Object[])">
|
||||
<summary>
|
||||
特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
|
||||
</summary>
|
||||
<param name="that"></param>
|
||||
<param name="args"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:FreeUtil.NewMongodbId">
|
||||
<summary>
|
||||
生成类似Mongodb的ObjectId有序、不重复Guid
|
||||
@ -2520,11 +2330,6 @@
|
||||
<param name="handler">事务体 () => {}</param>
|
||||
<param name="timeout">超时,未执行完将自动提交</param>
|
||||
</member>
|
||||
<member name="P:IFreeSql.Cache">
|
||||
<summary>
|
||||
缓存
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IFreeSql.Ado">
|
||||
<summary>
|
||||
数据库访问对象
|
||||
@ -2545,36 +2350,5 @@
|
||||
DbFirst 模式开发相关方法
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MygisTypesExtensions.Distance(MygisPoint,MygisPoint)">
|
||||
<summary>
|
||||
测量两个经纬度的距离,返回单位:米
|
||||
</summary>
|
||||
<param name="that">经纬坐标1</param>
|
||||
<param name="point">经纬坐标2</param>
|
||||
<returns>返回距离(单位:米)</returns>
|
||||
</member>
|
||||
<member name="M:PostgreSQLTypesExtensions.Distance(NpgsqlTypes.NpgsqlPoint,NpgsqlTypes.NpgsqlPoint)">
|
||||
<summary>
|
||||
测量两个经纬度的距离,返回单位:米
|
||||
</summary>
|
||||
<param name="that">经纬坐标1</param>
|
||||
<param name="point">经纬坐标2</param>
|
||||
<returns>返回距离(单位:米)</returns>
|
||||
</member>
|
||||
<member name="M:PostgreSQLTypesExtensions.Distance(Npgsql.LegacyPostgis.PostgisPoint,Npgsql.LegacyPostgis.PostgisPoint)">
|
||||
<summary>
|
||||
测量两个经纬度的距离,返回单位:米
|
||||
</summary>
|
||||
<param name="that">经纬坐标1</param>
|
||||
<param name="point">经纬坐标2</param>
|
||||
<returns>返回距离(单位:米)</returns>
|
||||
</member>
|
||||
<member name="M:PostgreSQLTypesExtensions.ToBitArray(System.String)">
|
||||
<summary>
|
||||
将 1010101010 这样的二进制字符串转换成 BitArray
|
||||
</summary>
|
||||
<param name="_1010Str">1010101010</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
|
@ -1,12 +1,8 @@
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace FreeSql {
|
||||
public class FreeSqlBuilder {
|
||||
IDistributedCache _cache;
|
||||
ILogger _logger;
|
||||
DataType _dataType;
|
||||
string _masterConnectionString;
|
||||
string[] _slaveConnectionString;
|
||||
@ -19,25 +15,6 @@ namespace FreeSql {
|
||||
Action<DbCommand> _aopCommandExecuting = null;
|
||||
Action<DbCommand, string> _aopCommandExecuted = null;
|
||||
|
||||
/// <summary>
|
||||
/// 使用缓存,不指定默认使用内存
|
||||
/// </summary>
|
||||
/// <param name="cache">缓存实现</param>
|
||||
/// <returns></returns>
|
||||
public FreeSqlBuilder UseCache(IDistributedCache cache) {
|
||||
_cache = cache;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用日志,不指定默认输出控制台
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
/// <returns></returns>
|
||||
public FreeSqlBuilder UseLogger(ILogger logger) {
|
||||
_logger = logger;
|
||||
return this;
|
||||
}
|
||||
/// <summary>
|
||||
/// 使用连接串
|
||||
/// </summary>
|
||||
@ -127,14 +104,27 @@ namespace FreeSql {
|
||||
public IFreeSql Build() => Build<IFreeSql>();
|
||||
public IFreeSql<TMark> Build<TMark>() {
|
||||
IFreeSql<TMark> ret = null;
|
||||
Type type = null;
|
||||
switch(_dataType) {
|
||||
case DataType.MySql: ret = new MySql.MySqlProvider<TMark>(_cache, _logger, _masterConnectionString, _slaveConnectionString); break;
|
||||
case DataType.SqlServer: ret = new SqlServer.SqlServerProvider<TMark>(_cache, _logger, _masterConnectionString, _slaveConnectionString); break;
|
||||
case DataType.PostgreSQL: ret = new PostgreSQL.PostgreSQLProvider<TMark>(_cache, _logger, _masterConnectionString, _slaveConnectionString); break;
|
||||
case DataType.Oracle: ret = new Oracle.OracleProvider<TMark>(_cache, _logger, _masterConnectionString, _slaveConnectionString); break;
|
||||
case DataType.Sqlite: ret = new Sqlite.SqliteProvider<TMark>(_cache, _logger, _masterConnectionString, _slaveConnectionString); break;
|
||||
case DataType.MySql:
|
||||
type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(typeof(TMark));
|
||||
if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载");
|
||||
break;
|
||||
case DataType.SqlServer: type = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(typeof(TMark));
|
||||
if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.SqlServer.dll,可前往 nuget 下载");
|
||||
break;
|
||||
case DataType.PostgreSQL: type = Type.GetType("FreeSql.PostgreSQL.PostgreSQLProvider`1,FreeSql.Provider.PostgreSQL")?.MakeGenericType(typeof(TMark));
|
||||
if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.PostgreSQL.dll,可前往 nuget 下载");
|
||||
break;
|
||||
case DataType.Oracle: type = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(typeof(TMark));
|
||||
if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Oracle.dll,可前往 nuget 下载");
|
||||
break;
|
||||
case DataType.Sqlite: type = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(typeof(TMark));
|
||||
if (type == null) throw new Exception("缺少 FreeSql 数据库实现包:FreeSql.Provider.Sqlite.dll,可前往 nuget 下载");
|
||||
break;
|
||||
default: throw new Exception("未指定 UseConnectionString");
|
||||
}
|
||||
ret = Activator.CreateInstance(type, new object[] { _masterConnectionString, _slaveConnectionString }) as IFreeSql<TMark>;
|
||||
if (ret != null) {
|
||||
ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure;
|
||||
|
||||
|
@ -31,38 +31,4 @@ public static class FreeUtil {
|
||||
var guid = $"{uninxtime.ToString("x8").PadLeft(8, '0')}{__staticMachine.ToString("x8").PadLeft(8, '0').Substring(2, 6)}{__staticPid.ToString("x8").PadLeft(8, '0').Substring(6, 2)}{increment.ToString("x8").PadLeft(8, '0')}{rand.ToString("x8").PadLeft(8, '0')}";
|
||||
return Guid.Parse(guid);
|
||||
}
|
||||
|
||||
internal static void PrevReheatConnectionPool(ObjectPool<DbConnection> pool, int minPoolSize) {
|
||||
if (minPoolSize <= 0) minPoolSize = Math.Min(5, pool.Policy.PoolSize);
|
||||
if (minPoolSize > pool.Policy.PoolSize) minPoolSize = pool.Policy.PoolSize;
|
||||
var initTestOk = true;
|
||||
var initStartTime = DateTime.Now;
|
||||
var initConns = new ConcurrentBag<Object<DbConnection>>();
|
||||
|
||||
try {
|
||||
var conn = pool.Get();
|
||||
initConns.Add(conn);
|
||||
pool.Policy.OnCheckAvailable(conn);
|
||||
} catch {
|
||||
initTestOk = false; //预热一次失败,后面将不进行
|
||||
}
|
||||
for (var a = 1; initTestOk && a < minPoolSize; a += 10) {
|
||||
if (initStartTime.Subtract(DateTime.Now).TotalSeconds > 3) break; //预热耗时超过3秒,退出
|
||||
var b = Math.Min(minPoolSize - a, 10); //每10个预热
|
||||
var initTasks = new Task[b];
|
||||
for (var c = 0; c < b; c++) {
|
||||
initTasks[c] = Task.Run(() => {
|
||||
try {
|
||||
var conn = pool.Get();
|
||||
initConns.Add(conn);
|
||||
pool.Policy.OnCheckAvailable(conn);
|
||||
} catch {
|
||||
initTestOk = false; //有失败,下一组退出预热
|
||||
}
|
||||
});
|
||||
}
|
||||
Task.WaitAll(initTasks);
|
||||
}
|
||||
while (initConns.TryTake(out var conn)) pool.Return(conn);
|
||||
}
|
||||
}
|
@ -1,644 +0,0 @@
|
||||
using Microsoft.CSharp;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
|
||||
namespace FreeSql.Generator {
|
||||
public class TemplateEngin : IDisposable {
|
||||
public interface ITemplateOutput {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="tOuTpUt">返回内容</param>
|
||||
/// <param name="oPtIoNs">渲染对象</param>
|
||||
/// <param name="rEfErErFiLeNaMe">当前文件路径</param>
|
||||
/// <param name="tEmPlAtEsEnDeR"></param>
|
||||
/// <returns></returns>
|
||||
TemplateReturnInfo OuTpUt(StringBuilder tOuTpUt, IDictionary oPtIoNs, string rEfErErFiLeNaMe, TemplateEngin tEmPlAtEsEnDeR);
|
||||
}
|
||||
public class TemplateReturnInfo {
|
||||
public Dictionary<string, int[]> Blocks;
|
||||
public StringBuilder Sb;
|
||||
}
|
||||
public delegate bool TemplateIf(object exp);
|
||||
public delegate void TemplatePrint(params object[] parms);
|
||||
|
||||
private static int _view = 0;
|
||||
private static Regex _reg = new Regex(@"\{(\$TEMPLATE__CODE|\/\$TEMPLATE__CODE|import\s+|module\s+|extends\s+|block\s+|include\s+|for\s+|if\s+|#|\/for|elseif|else|\/if|\/block|\/module)([^\}]*)\}", RegexOptions.Compiled);
|
||||
private static Regex _reg_forin = new Regex(@"^([\w_]+)\s*,?\s*([\w_]+)?\s+in\s+(.+)", RegexOptions.Compiled);
|
||||
private static Regex _reg_foron = new Regex(@"^([\w_]+)\s*,?\s*([\w_]+)?,?\s*([\w_]+)?\s+on\s+(.+)", RegexOptions.Compiled);
|
||||
private static Regex _reg_forab = new Regex(@"^([\w_]+)\s+([^,]+)\s*,\s*(.+)", RegexOptions.Compiled);
|
||||
private static Regex _reg_miss = new Regex(@"\{\/?miss\}", RegexOptions.Compiled);
|
||||
private static Regex _reg_code = new Regex(@"(\{%|%\})", RegexOptions.Compiled);
|
||||
private static Regex _reg_syntax = new Regex(@"<(\w+)\s+@(if|for|else)\s*=""([^""]*)""", RegexOptions.Compiled);
|
||||
private static Regex _reg_htmltag = new Regex(@"<\/?\w+[^>]*>", RegexOptions.Compiled);
|
||||
private static Regex _reg_blank = new Regex(@"\s+", RegexOptions.Compiled);
|
||||
private static Regex _reg_complie_undefined = new Regex(@"(当前上下文中不存在名称)?“(\w+)”", RegexOptions.Compiled);
|
||||
|
||||
private Dictionary<string, ITemplateOutput> _cache = new Dictionary<string, ITemplateOutput>();
|
||||
private object _cache_lock = new object();
|
||||
private string _viewDir;
|
||||
private string[] _usings;
|
||||
private FileSystemWatcher _fsw = new FileSystemWatcher();
|
||||
|
||||
public TemplateEngin(string viewDir, params string[] usings) {
|
||||
_viewDir = Utils.TranslateUrl(viewDir);
|
||||
_usings = usings;
|
||||
_fsw = new FileSystemWatcher(_viewDir);
|
||||
_fsw.IncludeSubdirectories = true;
|
||||
_fsw.Changed += ViewDirChange;
|
||||
_fsw.Renamed += ViewDirChange;
|
||||
_fsw.EnableRaisingEvents = true;
|
||||
}
|
||||
public void Dispose() {
|
||||
_fsw.Dispose();
|
||||
}
|
||||
void ViewDirChange(object sender, FileSystemEventArgs e) {
|
||||
string filename = e.FullPath.ToLower();
|
||||
lock (_cache_lock) {
|
||||
_cache.Remove(filename);
|
||||
}
|
||||
}
|
||||
public TemplateReturnInfo RenderFile2(StringBuilder sb, IDictionary options, string filename, string refererFilename) {
|
||||
if (filename[0] == '/' || string.IsNullOrEmpty(refererFilename)) refererFilename = _viewDir;
|
||||
//else refererFilename = Path.GetDirectoryName(refererFilename);
|
||||
string filename2 = Utils.TranslateUrl(filename, refererFilename);
|
||||
ITemplateOutput tpl;
|
||||
if (_cache.TryGetValue(filename2, out tpl) == false) {
|
||||
string tplcode = File.Exists(filename2) == false ? string.Concat("文件不存在 ", filename) : Utils.ReadTextFile(filename2);
|
||||
tpl = Parser(tplcode, _usings, options);
|
||||
lock (_cache_lock) {
|
||||
if (_cache.ContainsKey(filename2) == false) {
|
||||
_cache.Add(filename2, tpl);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
return tpl.OuTpUt(sb, options, filename2, this);
|
||||
} catch (Exception ex) {
|
||||
TemplateReturnInfo ret = sb == null ?
|
||||
new TemplateReturnInfo { Sb = new StringBuilder(), Blocks = new Dictionary<string, int[]>() } :
|
||||
new TemplateReturnInfo { Sb = sb, Blocks = new Dictionary<string, int[]>() };
|
||||
ret.Sb.Append(refererFilename);
|
||||
ret.Sb.Append(" -> ");
|
||||
ret.Sb.Append(filename);
|
||||
ret.Sb.Append("\r\n");
|
||||
ret.Sb.Append(ex.Message);
|
||||
ret.Sb.Append("\r\n");
|
||||
ret.Sb.Append(ex.StackTrace);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
public string RenderFile(string filename, IDictionary options) {
|
||||
TemplateReturnInfo ret = this.RenderFile2(null, options, filename, null);
|
||||
return ret.Sb.ToString();
|
||||
}
|
||||
private static ITemplateOutput Parser(string tplcode, string[] usings, IDictionary options) {
|
||||
int view = Interlocked.Increment(ref _view);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
IDictionary options_copy = new Hashtable();
|
||||
foreach (DictionaryEntry options_de in options) options_copy[options_de.Key] = options_de.Value;
|
||||
sb.AppendFormat(@"
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;{1}
|
||||
|
||||
//namespace TplDynamicCodeGenerate {{
|
||||
public class TplDynamicCodeGenerate_view{0} : FreeSql.Generator.TemplateEngin.ITemplateOutput {{
|
||||
public FreeSql.Generator.TemplateEngin.TemplateReturnInfo OuTpUt(StringBuilder tOuTpUt, IDictionary oPtIoNs, string rEfErErFiLeNaMe, FreeSql.Generator.TemplateEngin tEmPlAtEsEnDeR) {{
|
||||
FreeSql.Generator.TemplateEngin.TemplateReturnInfo rTn = tOuTpUt == null ?
|
||||
new FreeSql.Generator.TemplateEngin.TemplateReturnInfo {{ Sb = (tOuTpUt = new StringBuilder()), Blocks = new Dictionary<string, int[]>() }} :
|
||||
new FreeSql.Generator.TemplateEngin.TemplateReturnInfo {{ Sb = tOuTpUt, Blocks = new Dictionary<string, int[]>() }};
|
||||
Dictionary<string, int[]> TPL__blocks = rTn.Blocks;
|
||||
Stack<int[]> TPL__blocks_stack = new Stack<int[]>();
|
||||
int[] TPL__blocks_stack_peek;
|
||||
List<IDictionary> TPL__forc = new List<IDictionary>();
|
||||
Func<IDictionary> pRoCeSsOpTiOnS = new Func<IDictionary>(delegate () {{
|
||||
IDictionary nEwoPtIoNs = new Hashtable();
|
||||
foreach (DictionaryEntry oPtIoNs_dE in oPtIoNs)
|
||||
nEwoPtIoNs[oPtIoNs_dE.Key] = oPtIoNs_dE.Value;
|
||||
foreach (IDictionary TPL__forc_dIc in TPL__forc)
|
||||
foreach (DictionaryEntry TPL__forc_dIc_dE in TPL__forc_dIc)
|
||||
nEwoPtIoNs[TPL__forc_dIc_dE.Key] = TPL__forc_dIc_dE.Value;
|
||||
return nEwoPtIoNs;
|
||||
}});
|
||||
FreeSql.Generator.TemplateEngin.TemplateIf tPlIf = delegate(object exp) {{
|
||||
if (exp is bool) return (bool)exp;
|
||||
if (exp == null) return false;
|
||||
if (exp is int && (int)exp == 0) return false;
|
||||
if (exp is string && (string)exp == string.Empty) return false;
|
||||
if (exp is long && (long)exp == 0) return false;
|
||||
if (exp is short && (short)exp == 0) return false;
|
||||
if (exp is byte && (byte)exp == 0) return false;
|
||||
if (exp is double && (double)exp == 0) return false;
|
||||
if (exp is float && (float)exp == 0) return false;
|
||||
if (exp is decimal && (decimal)exp == 0) return false;
|
||||
return true;
|
||||
}};
|
||||
FreeSql.Generator.TemplateEngin.TemplatePrint print = delegate(object[] pArMs) {{
|
||||
if (pArMs == null || pArMs.Length == 0) return;
|
||||
foreach (object pArMs_A in pArMs) if (pArMs_A != null) tOuTpUt.Append(pArMs_A);
|
||||
}};
|
||||
FreeSql.Generator.TemplateEngin.TemplatePrint Print = print;", view, usings?.Any() == true ? $"\r\nusing {string.Join(";\r\nusing ", usings)};" : "");
|
||||
|
||||
#region {miss}...{/miss}块内容将不被解析
|
||||
string[] tmp_content_arr = _reg_miss.Split(tplcode);
|
||||
if (tmp_content_arr.Length > 1) {
|
||||
sb.AppendFormat(@"
|
||||
string[] TPL__MISS = new string[{0}];", Math.Ceiling(1.0 * (tmp_content_arr.Length - 1) / 2));
|
||||
int miss_len = -1;
|
||||
for (int a = 1; a < tmp_content_arr.Length; a += 2) {
|
||||
sb.Append(string.Concat(@"
|
||||
TPL__MISS[", ++miss_len, @"] = """, Utils.GetConstString(tmp_content_arr[a]), @""";"));
|
||||
tmp_content_arr[a] = string.Concat("{#TPL__MISS[", miss_len, "]}");
|
||||
}
|
||||
tplcode = string.Join("", tmp_content_arr);
|
||||
}
|
||||
#endregion
|
||||
#region 扩展语法如 <div @if="表达式"></div>
|
||||
tplcode = htmlSyntax(tplcode, 3); //<div @if="c#表达式" @for="index 1,100"></div>
|
||||
//处理 {% %} 块 c#代码
|
||||
tmp_content_arr = _reg_code.Split(tplcode);
|
||||
if (tmp_content_arr.Length == 1) {
|
||||
tplcode = Utils.GetConstString(tplcode)
|
||||
.Replace("{%", "{$TEMPLATE__CODE}")
|
||||
.Replace("%}", "{/$TEMPLATE__CODE}");
|
||||
} else {
|
||||
tmp_content_arr[0] = Utils.GetConstString(tmp_content_arr[0]);
|
||||
for (int a = 1; a < tmp_content_arr.Length; a += 4) {
|
||||
tmp_content_arr[a] = "{$TEMPLATE__CODE}";
|
||||
tmp_content_arr[a + 2] = "{/$TEMPLATE__CODE}";
|
||||
tmp_content_arr[a + 3] = Utils.GetConstString(tmp_content_arr[a + 3]);
|
||||
}
|
||||
tplcode = string.Join("", tmp_content_arr);
|
||||
}
|
||||
#endregion
|
||||
sb.Append(@"
|
||||
tOuTpUt.Append(""");
|
||||
|
||||
string error = null;
|
||||
int tpl_tmpid = 0;
|
||||
int forc_i = 0;
|
||||
string extends = null;
|
||||
Stack<string> codeTree = new Stack<string>();
|
||||
Stack<string> forEndRepl = new Stack<string>();
|
||||
sb.Append(_reg.Replace(tplcode, delegate (Match m) {
|
||||
string _0 = m.Groups[0].Value;
|
||||
if (!string.IsNullOrEmpty(error)) return _0;
|
||||
|
||||
string _1 = m.Groups[1].Value.Trim(' ', '\t');
|
||||
string _2 = m.Groups[2].Value
|
||||
.Replace("\\\\", "\\")
|
||||
.Replace("\\\"", "\"");
|
||||
_2 = Utils.ReplaceSingleQuote(_2);
|
||||
|
||||
switch (_1) {
|
||||
#region $TEMPLATE__CODE--------------------------------------------------
|
||||
case "$TEMPLATE__CODE":
|
||||
codeTree.Push(_1);
|
||||
return @""");
|
||||
";
|
||||
case "/$TEMPLATE__CODE":
|
||||
string pop = codeTree.Pop();
|
||||
if (pop != "$TEMPLATE__CODE") {
|
||||
codeTree.Push(pop);
|
||||
error = "编译出错,{% 与 %} 并没有配对";
|
||||
return _0;
|
||||
}
|
||||
return @"
|
||||
tOuTpUt.Append(""";
|
||||
#endregion
|
||||
case "include":
|
||||
return string.Format(@""");
|
||||
tEmPlAtEsEnDeR.RenderFile2(tOuTpUt, pRoCeSsOpTiOnS(), ""{0}"", rEfErErFiLeNaMe);
|
||||
tOuTpUt.Append(""", _2);
|
||||
case "import":
|
||||
return _0;
|
||||
case "module":
|
||||
return _0;
|
||||
case "/module":
|
||||
return _0;
|
||||
case "extends":
|
||||
//{extends ../inc/layout.html}
|
||||
if (string.IsNullOrEmpty(extends) == false) return _0;
|
||||
extends = _2;
|
||||
return string.Empty;
|
||||
case "block":
|
||||
codeTree.Push("block");
|
||||
return string.Format(@""");
|
||||
TPL__blocks_stack_peek = new int[] {{ tOuTpUt.Length, 0 }};
|
||||
TPL__blocks_stack.Push(TPL__blocks_stack_peek);
|
||||
TPL__blocks.Add(""{0}"", TPL__blocks_stack_peek);
|
||||
tOuTpUt.Append(""", _2.Trim(' ', '\t'));
|
||||
case "/block":
|
||||
codeTreeEnd(codeTree, "block");
|
||||
return @""");
|
||||
TPL__blocks_stack_peek = TPL__blocks_stack.Pop();
|
||||
TPL__blocks_stack_peek[1] = tOuTpUt.Length - TPL__blocks_stack_peek[0];
|
||||
tOuTpUt.Append(""";
|
||||
|
||||
#region ##---------------------------------------------------------
|
||||
case "#":
|
||||
if (_2[0] == '#')
|
||||
return string.Format(@""");
|
||||
try {{ Print({0}); }} catch {{ }}
|
||||
tOuTpUt.Append(""", _2.Substring(1));
|
||||
return string.Format(@""");
|
||||
Print({0});
|
||||
tOuTpUt.Append(""", _2);
|
||||
#endregion
|
||||
#region for--------------------------------------------------------
|
||||
case "for":
|
||||
forc_i++;
|
||||
int cur_tpl_tmpid = tpl_tmpid;
|
||||
string sb_endRepl = string.Empty;
|
||||
StringBuilder sbfor = new StringBuilder();
|
||||
sbfor.Append(@""");");
|
||||
Match mfor = _reg_forin.Match(_2);
|
||||
if (mfor.Success) {
|
||||
string mfor1 = mfor.Groups[1].Value.Trim(' ', '\t');
|
||||
string mfor2 = mfor.Groups[2].Value.Trim(' ', '\t');
|
||||
sbfor.AppendFormat(@"
|
||||
//new Action(delegate () {{
|
||||
IDictionary TPL__tmp{0} = new Hashtable();
|
||||
TPL__forc.Add(TPL__tmp{0});
|
||||
var TPL__tmp{1} = {3};
|
||||
var TPL__tmp{2} = {4};", ++tpl_tmpid, ++tpl_tmpid, ++tpl_tmpid, mfor.Groups[3].Value, mfor1);
|
||||
sb_endRepl = string.Concat(sb_endRepl, string.Format(@"
|
||||
{0} = TPL__tmp{1};", mfor1, cur_tpl_tmpid + 3));
|
||||
if (options_copy.Contains(mfor1) == false) options_copy[mfor1] = null;
|
||||
if (!string.IsNullOrEmpty(mfor2)) {
|
||||
sbfor.AppendFormat(@"
|
||||
var TPL__tmp{1} = {0};
|
||||
{0} = 0;", mfor2, ++tpl_tmpid);
|
||||
sb_endRepl = string.Concat(sb_endRepl, string.Format(@"
|
||||
{0} = TPL__tmp{1};", mfor2, tpl_tmpid));
|
||||
if (options_copy.Contains(mfor2) == false) options_copy[mfor2] = null;
|
||||
}
|
||||
sbfor.AppendFormat(@"
|
||||
if (TPL__tmp{1} != null)
|
||||
foreach (var TPL__tmp{0} in TPL__tmp{1}) {{", ++tpl_tmpid, cur_tpl_tmpid + 2);
|
||||
if (!string.IsNullOrEmpty(mfor2))
|
||||
sbfor.AppendFormat(@"
|
||||
TPL__tmp{1}[""{0}""] = ++ {0};", mfor2, cur_tpl_tmpid + 1);
|
||||
sbfor.AppendFormat(@"
|
||||
TPL__tmp{1}[""{0}""] = TPL__tmp{2};
|
||||
{0} = TPL__tmp{2};
|
||||
tOuTpUt.Append(""", mfor1, cur_tpl_tmpid + 1, tpl_tmpid);
|
||||
codeTree.Push("for");
|
||||
forEndRepl.Push(sb_endRepl);
|
||||
return sbfor.ToString();
|
||||
}
|
||||
mfor = _reg_foron.Match(_2);
|
||||
if (mfor.Success) {
|
||||
string mfor1 = mfor.Groups[1].Value.Trim(' ', '\t');
|
||||
string mfor2 = mfor.Groups[2].Value.Trim(' ', '\t');
|
||||
string mfor3 = mfor.Groups[3].Value.Trim(' ', '\t');
|
||||
sbfor.AppendFormat(@"
|
||||
//new Action(delegate () {{
|
||||
IDictionary TPL__tmp{0} = new Hashtable();
|
||||
TPL__forc.Add(TPL__tmp{0});
|
||||
var TPL__tmp{1} = {3};
|
||||
var TPL__tmp{2} = {4};", ++tpl_tmpid, ++tpl_tmpid, ++tpl_tmpid, mfor.Groups[4].Value, mfor1);
|
||||
sb_endRepl = string.Concat(sb_endRepl, string.Format(@"
|
||||
{0} = TPL__tmp{1};", mfor1, cur_tpl_tmpid + 3));
|
||||
if (options_copy.Contains(mfor1) == false) options_copy[mfor1] = null;
|
||||
if (!string.IsNullOrEmpty(mfor2)) {
|
||||
sbfor.AppendFormat(@"
|
||||
var TPL__tmp{1} = {0};", mfor2, ++tpl_tmpid);
|
||||
sb_endRepl = string.Concat(sb_endRepl, string.Format(@"
|
||||
{0} = TPL__tmp{1};", mfor2, tpl_tmpid));
|
||||
if (options_copy.Contains(mfor2) == false) options_copy[mfor2] = null;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(mfor3)) {
|
||||
sbfor.AppendFormat(@"
|
||||
var TPL__tmp{1} = {0};
|
||||
{0} = 0;", mfor3, ++tpl_tmpid);
|
||||
sb_endRepl = string.Concat(sb_endRepl, string.Format(@"
|
||||
{0} = TPL__tmp{1};", mfor3, tpl_tmpid));
|
||||
if (options_copy.Contains(mfor3) == false) options_copy[mfor3] = null;
|
||||
}
|
||||
sbfor.AppendFormat(@"
|
||||
if (TPL__tmp{2} != null)
|
||||
foreach (DictionaryEntry TPL__tmp{1} in TPL__tmp{2}) {{
|
||||
{0} = TPL__tmp{1}.Key;
|
||||
TPL__tmp{3}[""{0}""] = {0};", mfor1, ++tpl_tmpid, cur_tpl_tmpid + 2, cur_tpl_tmpid + 1);
|
||||
if (!string.IsNullOrEmpty(mfor2))
|
||||
sbfor.AppendFormat(@"
|
||||
{0} = TPL__tmp{1}.Value;
|
||||
TPL__tmp{2}[""{0}""] = {0};", mfor2, tpl_tmpid, cur_tpl_tmpid + 1);
|
||||
if (!string.IsNullOrEmpty(mfor3))
|
||||
sbfor.AppendFormat(@"
|
||||
TPL__tmp{1}[""{0}""] = ++ {0};", mfor3, cur_tpl_tmpid + 1);
|
||||
sbfor.AppendFormat(@"
|
||||
tOuTpUt.Append(""");
|
||||
codeTree.Push("for");
|
||||
forEndRepl.Push(sb_endRepl);
|
||||
return sbfor.ToString();
|
||||
}
|
||||
mfor = _reg_forab.Match(_2);
|
||||
if (mfor.Success) {
|
||||
string mfor1 = mfor.Groups[1].Value.Trim(' ', '\t');
|
||||
sbfor.AppendFormat(@"
|
||||
//new Action(delegate () {{
|
||||
IDictionary TPL__tmp{0} = new Hashtable();
|
||||
TPL__forc.Add(TPL__tmp{0});
|
||||
var TPL__tmp{1} = {5};
|
||||
{5} = {3} - 1;
|
||||
if ({5} == null) {5} = 0;
|
||||
var TPL__tmp{2} = {4} + 1;
|
||||
while (++{5} < TPL__tmp{2}) {{
|
||||
TPL__tmp{0}[""{5}""] = {5};
|
||||
tOuTpUt.Append(""", ++tpl_tmpid, ++tpl_tmpid, ++tpl_tmpid, mfor.Groups[2].Value, mfor.Groups[3].Value, mfor1);
|
||||
sb_endRepl = string.Concat(sb_endRepl, string.Format(@"
|
||||
{0} = TPL__tmp{1};", mfor1, cur_tpl_tmpid + 1));
|
||||
if (options_copy.Contains(mfor1) == false) options_copy[mfor1] = null;
|
||||
codeTree.Push("for");
|
||||
forEndRepl.Push(sb_endRepl);
|
||||
return sbfor.ToString();
|
||||
}
|
||||
return _0;
|
||||
case "/for":
|
||||
if (--forc_i < 0) return _0;
|
||||
codeTreeEnd(codeTree, "for");
|
||||
return string.Format(@""");
|
||||
}}{0}
|
||||
TPL__forc.RemoveAt(TPL__forc.Count - 1);
|
||||
//}})();
|
||||
tOuTpUt.Append(""", forEndRepl.Pop());
|
||||
#endregion
|
||||
#region if---------------------------------------------------------
|
||||
case "if":
|
||||
codeTree.Push("if");
|
||||
return string.Format(@""");
|
||||
if ({1}tPlIf({0})) {{
|
||||
tOuTpUt.Append(""", _2[0] == '!' ? _2.Substring(1) : _2, _2[0] == '!' ? '!' : ' ');
|
||||
case "elseif":
|
||||
codeTreeEnd(codeTree, "if");
|
||||
codeTree.Push("if");
|
||||
return string.Format(@""");
|
||||
}} else if ({1}tPlIf({0})) {{
|
||||
tOuTpUt.Append(""", _2[0] == '!' ? _2.Substring(1) : _2, _2[0] == '!' ? '!' : ' ');
|
||||
case "else":
|
||||
codeTreeEnd(codeTree, "if");
|
||||
codeTree.Push("if");
|
||||
return @""");
|
||||
} else {
|
||||
tOuTpUt.Append(""";
|
||||
case "/if":
|
||||
codeTreeEnd(codeTree, "if");
|
||||
return @""");
|
||||
}
|
||||
tOuTpUt.Append(""";
|
||||
#endregion
|
||||
}
|
||||
return _0;
|
||||
}));
|
||||
|
||||
sb.Append(@""");");
|
||||
if (string.IsNullOrEmpty(extends) == false) {
|
||||
sb.AppendFormat(@"
|
||||
FreeSql.Generator.TemplateEngin.TemplateReturnInfo eXtEnDs_ReT = tEmPlAtEsEnDeR.RenderFile2(null, pRoCeSsOpTiOnS(), ""{0}"", rEfErErFiLeNaMe);
|
||||
string rTn_Sb_string = rTn.Sb.ToString();
|
||||
foreach(string eXtEnDs_ReT_blocks_key in eXtEnDs_ReT.Blocks.Keys) {{
|
||||
if (rTn.Blocks.ContainsKey(eXtEnDs_ReT_blocks_key)) {{
|
||||
int[] eXtEnDs_ReT_blocks_value = eXtEnDs_ReT.Blocks[eXtEnDs_ReT_blocks_key];
|
||||
eXtEnDs_ReT.Sb.Remove(eXtEnDs_ReT_blocks_value[0], eXtEnDs_ReT_blocks_value[1]);
|
||||
int[] rTn_blocks_value = rTn.Blocks[eXtEnDs_ReT_blocks_key];
|
||||
eXtEnDs_ReT.Sb.Insert(eXtEnDs_ReT_blocks_value[0], rTn_Sb_string.Substring(rTn_blocks_value[0], rTn_blocks_value[1]));
|
||||
foreach(string eXtEnDs_ReT_blocks_keyb in eXtEnDs_ReT.Blocks.Keys) {{
|
||||
if (eXtEnDs_ReT_blocks_keyb == eXtEnDs_ReT_blocks_key) continue;
|
||||
int[] eXtEnDs_ReT_blocks_valueb = eXtEnDs_ReT.Blocks[eXtEnDs_ReT_blocks_keyb];
|
||||
if (eXtEnDs_ReT_blocks_valueb[0] >= eXtEnDs_ReT_blocks_value[0])
|
||||
eXtEnDs_ReT_blocks_valueb[0] = eXtEnDs_ReT_blocks_valueb[0] - eXtEnDs_ReT_blocks_value[1] + rTn_blocks_value[1];
|
||||
}}
|
||||
eXtEnDs_ReT_blocks_value[1] = rTn_blocks_value[1];
|
||||
}}
|
||||
}}
|
||||
return eXtEnDs_ReT;
|
||||
", extends);
|
||||
} else {
|
||||
sb.Append(@"
|
||||
return rTn;");
|
||||
}
|
||||
sb.Append(@"
|
||||
}
|
||||
}
|
||||
//}
|
||||
");
|
||||
var str = "FreeSql.Generator.TemplateEngin.TemplatePrint Print = print;";
|
||||
int dim_idx = sb.ToString().IndexOf(str) + str.Length;
|
||||
foreach (string dic_name in options_copy.Keys) {
|
||||
sb.Insert(dim_idx, string.Format(@"
|
||||
dynamic {0} = oPtIoNs[""{0}""];", dic_name));
|
||||
}
|
||||
//Console.WriteLine(sb.ToString());
|
||||
return Complie(sb.ToString(), @"TplDynamicCodeGenerate_view" + view);
|
||||
}
|
||||
private static string codeTreeEnd(Stack<string> codeTree, string tag) {
|
||||
string ret = string.Empty;
|
||||
Stack<int> pop = new Stack<int>();
|
||||
foreach (string ct in codeTree) {
|
||||
if (ct == "import" ||
|
||||
ct == "include") {
|
||||
pop.Push(1);
|
||||
} else if (ct == tag) {
|
||||
pop.Push(2);
|
||||
break;
|
||||
} else {
|
||||
if (string.IsNullOrEmpty(tag) == false) pop.Clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pop.Count == 0 && string.IsNullOrEmpty(tag) == false)
|
||||
return string.Concat("语法错误,{", tag, "} {/", tag, "} 并没配对");
|
||||
while (pop.Count > 0 && pop.Pop() > 0) codeTree.Pop();
|
||||
return ret;
|
||||
}
|
||||
#region htmlSyntax
|
||||
private static string htmlSyntax(string tplcode, int num) {
|
||||
|
||||
while (num-- > 0) {
|
||||
string[] arr = _reg_syntax.Split(tplcode);
|
||||
|
||||
if (arr.Length == 1) break;
|
||||
for (int a = 1; a < arr.Length; a += 4) {
|
||||
string tag = string.Concat('<', arr[a]);
|
||||
string end = string.Concat("</", arr[a], '>');
|
||||
int fc = 1;
|
||||
for (int b = a; fc > 0 && b < arr.Length; b += 4) {
|
||||
if (b > a && arr[a].ToLower() == arr[b].ToLower()) fc++;
|
||||
int bpos = 0;
|
||||
while (true) {
|
||||
int fa = arr[b + 3].IndexOf(tag, bpos);
|
||||
int fb = arr[b + 3].IndexOf(end, bpos);
|
||||
if (b == a) {
|
||||
var z = arr[b + 3].IndexOf("/>");
|
||||
if ((fb == -1 || z < fb) && z != -1) {
|
||||
var y = arr[b + 3].Substring(0, z + 2);
|
||||
if (_reg_htmltag.IsMatch(y) == false)
|
||||
fb = z - end.Length + 2;
|
||||
}
|
||||
}
|
||||
if (fa == -1 && fb == -1) break;
|
||||
if (fa != -1 && (fa < fb || fb == -1)) {
|
||||
fc++;
|
||||
bpos = fa + tag.Length;
|
||||
continue;
|
||||
}
|
||||
if (fb != -1) fc--;
|
||||
if (fc <= 0) {
|
||||
var a1 = arr[a + 1];
|
||||
var end3 = string.Concat("{/", a1, "}");
|
||||
if (a1.ToLower() == "else") {
|
||||
if (_reg_blank.Replace(arr[a - 4 + 3], "").EndsWith("{/if}", StringComparison.CurrentCultureIgnoreCase) == true) {
|
||||
var idx = arr[a - 4 + 3].IndexOf("{/if}");
|
||||
arr[a - 4 + 3] = string.Concat(arr[a - 4 + 3].Substring(0, idx), arr[a - 4 + 3].Substring(idx + 5));
|
||||
//如果 @else="有条件内容",则变换成 elseif 条件内容
|
||||
if (_reg_blank.Replace(arr[a + 2], "").Length > 0) a1 = "elseif";
|
||||
end3 = "{/if}";
|
||||
} else {
|
||||
arr[a] = string.Concat("指令 @", arr[a + 1], "='", arr[a + 2], "' 没紧接着 if/else 指令之后,无效. <", arr[a]);
|
||||
arr[a + 1] = arr[a + 2] = string.Empty;
|
||||
}
|
||||
}
|
||||
if (arr[a + 1].Length > 0) {
|
||||
if (_reg_blank.Replace(arr[a + 2], "").Length > 0 || a1.ToLower() == "else") {
|
||||
arr[b + 3] = string.Concat(arr[b + 3].Substring(0, fb + end.Length), end3, arr[b + 3].Substring(fb + end.Length));
|
||||
arr[a] = string.Concat("{", a1, " ", arr[a + 2], "}<", arr[a]);
|
||||
arr[a + 1] = arr[a + 2] = string.Empty;
|
||||
} else {
|
||||
arr[a] = string.Concat('<', arr[a]);
|
||||
arr[a + 1] = arr[a + 2] = string.Empty;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
bpos = fb + end.Length;
|
||||
}
|
||||
}
|
||||
if (fc > 0) {
|
||||
arr[a] = string.Concat("不严谨的html格式,请检查 ", arr[a], " 的结束标签, @", arr[a + 1], "='", arr[a + 2], "' 指令无效. <", arr[a]);
|
||||
arr[a + 1] = arr[a + 2] = string.Empty;
|
||||
}
|
||||
}
|
||||
if (arr.Length > 0) tplcode = string.Join(string.Empty, arr);
|
||||
}
|
||||
return tplcode;
|
||||
}
|
||||
#endregion
|
||||
#region Complie
|
||||
private static ITemplateOutput Complie(string cscode, string typename) {
|
||||
var assemly = _compiler.Value.CompileCode(cscode);
|
||||
var type = assemly.DefinedTypes.Where(a => a.FullName.EndsWith(typename)).FirstOrDefault();
|
||||
return Activator.CreateInstance(type) as ITemplateOutput;
|
||||
}
|
||||
internal static Lazy<CSScriptLib.RoslynEvaluator> _compiler = new Lazy<CSScriptLib.RoslynEvaluator>(() => {
|
||||
//var dlls = Directory.GetFiles(Directory.GetParent(Type.GetType("IFreeSql, FreeSql").Assembly.Location).FullName, "*.dll");
|
||||
var compiler = new CSScriptLib.RoslynEvaluator();
|
||||
compiler.DisableReferencingFromCode = false;
|
||||
//compiler.DebugBuild = true;
|
||||
//foreach (var dll in dlls) {
|
||||
// Console.WriteLine(dll);
|
||||
// var ass = Assembly.LoadFile(dll);
|
||||
// compiler.ReferenceAssembly(ass);
|
||||
//}
|
||||
compiler
|
||||
.ReferenceAssemblyOf<IFreeSql>()
|
||||
.ReferenceDomainAssemblies();
|
||||
return compiler;
|
||||
});
|
||||
|
||||
#endregion
|
||||
|
||||
#region Utils
|
||||
public class Utils {
|
||||
public static string ReplaceSingleQuote(object exp) {
|
||||
//将 ' 转换成 "
|
||||
string exp2 = string.Concat(exp);
|
||||
int quote_pos = -1;
|
||||
while (true) {
|
||||
int first_pos = quote_pos = exp2.IndexOf('\'', quote_pos + 1);
|
||||
if (quote_pos == -1) break;
|
||||
while (true) {
|
||||
quote_pos = exp2.IndexOf('\'', quote_pos + 1);
|
||||
if (quote_pos == -1) break;
|
||||
int r_cout = 0;
|
||||
for (int p = 1; true; p++) {
|
||||
if (exp2[quote_pos - p] == '\\') r_cout++;
|
||||
else break;
|
||||
}
|
||||
if (r_cout % 2 == 0/* && quote_pos - first_pos > 2*/) {
|
||||
string str1 = exp2.Substring(0, first_pos);
|
||||
string str2 = exp2.Substring(first_pos + 1, quote_pos - first_pos - 1);
|
||||
string str3 = exp2.Substring(quote_pos + 1);
|
||||
string str4 = str2.Replace("\"", "\\\"");
|
||||
quote_pos += str4.Length - str2.Length;
|
||||
exp2 = string.Concat(str1, "\"", str4, "\"", str3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (quote_pos == -1) break;
|
||||
}
|
||||
return exp2;
|
||||
}
|
||||
public static string GetConstString(object obj) {
|
||||
return string.Concat(obj)
|
||||
.Replace("\\", "\\\\")
|
||||
.Replace("\"", "\\\"")
|
||||
.Replace("\r", "\\r")
|
||||
.Replace("\n", "\\n");
|
||||
}
|
||||
|
||||
public static string ReadTextFile(string path) {
|
||||
byte[] bytes = ReadFile(path);
|
||||
return Encoding.UTF8.GetString(bytes).TrimStart((char)65279);
|
||||
}
|
||||
public static byte[] ReadFile(string path) {
|
||||
if (File.Exists(path)) {
|
||||
string destFileName = Path.GetTempFileName();
|
||||
File.Copy(path, destFileName, true);
|
||||
int read = 0;
|
||||
byte[] data = new byte[1024];
|
||||
using (MemoryStream ms = new MemoryStream()) {
|
||||
using (FileStream fs = new FileStream(destFileName, FileMode.OpenOrCreate, FileAccess.Read)) {
|
||||
do {
|
||||
read = fs.Read(data, 0, data.Length);
|
||||
if (read <= 0) break;
|
||||
ms.Write(data, 0, read);
|
||||
} while (true);
|
||||
}
|
||||
File.Delete(destFileName);
|
||||
data = ms.ToArray();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
return new byte[] { };
|
||||
}
|
||||
public static string TranslateUrl(string url) {
|
||||
return TranslateUrl(url, null);
|
||||
}
|
||||
public static string TranslateUrl(string url, string baseDir) {
|
||||
if (string.IsNullOrEmpty(baseDir)) baseDir = AppContext.BaseDirectory + "/";
|
||||
if (string.IsNullOrEmpty(url)) return Path.GetDirectoryName(baseDir);
|
||||
if (url.StartsWith("~/")) url = url.Substring(1);
|
||||
if (url.StartsWith("/")) return Path.GetFullPath(Path.Combine(Path.GetDirectoryName(baseDir), url.TrimStart('/')));
|
||||
if (url.StartsWith("\\")) return Path.GetFullPath(Path.Combine(Path.GetDirectoryName(baseDir), url.TrimStart('\\')));
|
||||
if (url.IndexOf(":\\") != -1) return url;
|
||||
return Path.GetFullPath(Path.Combine(Path.GetDirectoryName(baseDir), url));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
using FreeSql.DatabaseModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace FreeSql.Generator {
|
||||
public class TemplateGenerator {
|
||||
|
||||
public void Build(IDbFirst dbfirst, string templateDirectory, string outputDirectory, params string[] database) {
|
||||
if (dbfirst == null) throw new ArgumentException("dbfirst 参数不能为 null");
|
||||
if (string.IsNullOrEmpty(templateDirectory) || Directory.Exists(templateDirectory) == false) throw new ArgumentException("templateDirectory 目录不存在");
|
||||
if (string.IsNullOrEmpty(templateDirectory)) throw new ArgumentException("outputDirectory 不能为 null");
|
||||
if (database == null || database.Any() == false) throw new ArgumentException("database 参数不能为空");
|
||||
if (Directory.Exists(outputDirectory) == false) Directory.CreateDirectory(outputDirectory);
|
||||
templateDirectory = new DirectoryInfo(templateDirectory).FullName;
|
||||
outputDirectory = new DirectoryInfo(outputDirectory).FullName;
|
||||
if (templateDirectory.IndexOf(outputDirectory, StringComparison.CurrentCultureIgnoreCase) != -1) throw new ArgumentException("outputDirectory 目录不能设置在 templateDirectory 目录内");
|
||||
var tables = dbfirst.GetTablesByDatabase(database);
|
||||
var tpl = new TemplateEngin(templateDirectory, "FreeSql", "FreeSql.DatabaseModel");
|
||||
BuildEachDirectory(templateDirectory, outputDirectory, tpl, dbfirst, tables);
|
||||
tpl.Dispose();
|
||||
}
|
||||
|
||||
void BuildEachDirectory(string templateDirectory, string outputDirectory, TemplateEngin tpl, IDbFirst dbfirst, List<DbTableInfo> tables) {
|
||||
if (Directory.Exists(outputDirectory) == false) Directory.CreateDirectory(outputDirectory);
|
||||
var files = Directory.GetFiles(templateDirectory);
|
||||
foreach (var file in files) {
|
||||
var fi = new FileInfo(file);
|
||||
if (string.Compare(fi.Extension, ".FreeSql", true) == 0) {
|
||||
var outputExtension = "." + fi.Name.Split('.')[1];
|
||||
if (fi.Name.StartsWith("for-table.")) {
|
||||
foreach (var table in tables) {
|
||||
var result = tpl.RenderFile(file, new Dictionary<string, object>() { { "table", table }, { "dbfirst", dbfirst } });
|
||||
if (result.EndsWith("return;")) continue;
|
||||
var outputName = table.Name + outputExtension;
|
||||
var mcls = Regex.Match(result, @"\s+class\s+(\w+)");
|
||||
if (mcls.Success) outputName = mcls.Groups[1].Value + outputExtension;
|
||||
var outputStream = Encoding.UTF8.GetBytes(result);
|
||||
var fullname = outputDirectory + "/" + outputName;
|
||||
if (File.Exists(fullname)) File.Delete(fullname);
|
||||
using (var outfs = File.Open(fullname, FileMode.OpenOrCreate, FileAccess.Write)) {
|
||||
outfs.Write(outputStream, 0, outputStream.Length);
|
||||
outfs.Close();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
var result = tpl.RenderFile(file, new Dictionary<string, object>() { { "tables", tables }, { "dbfirst", dbfirst } });
|
||||
var outputName = fi.Name;
|
||||
var mcls = Regex.Match(result, @"\s+class\s+(\w+)");
|
||||
if (mcls.Success) outputName = mcls.Groups[1].Value + outputExtension;
|
||||
var outputStream = Encoding.UTF8.GetBytes(result);
|
||||
var fullname = outputDirectory + "/" + outputName;
|
||||
if (File.Exists(fullname)) File.Delete(fullname);
|
||||
using (var outfs = File.Open(fullname, FileMode.OpenOrCreate, FileAccess.Write)) {
|
||||
outfs.Write(outputStream, 0, outputStream.Length);
|
||||
outfs.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
File.Copy(file, outputDirectory + file.Replace(templateDirectory, ""), true);
|
||||
}
|
||||
var dirs = Directory.GetDirectories(templateDirectory);
|
||||
foreach(var dir in dirs) {
|
||||
BuildEachDirectory(dir, outputDirectory + dir.Replace(templateDirectory, ""), tpl, dbfirst, tables);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -108,13 +108,6 @@ namespace FreeSql {
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
TSelect Master();
|
||||
/// <summary>
|
||||
/// 缓存查询结果
|
||||
/// </summary>
|
||||
/// <param name="seconds">缓存秒数</param>
|
||||
/// <param name="key">缓存key</param>
|
||||
/// <returns></returns>
|
||||
TSelect Caching(int seconds, string key = null);
|
||||
|
||||
/// <summary>
|
||||
/// 左联查询,使用导航属性自动生成SQL
|
||||
|
@ -46,11 +46,6 @@ namespace FreeSql {
|
||||
/// 当前线程的事务
|
||||
/// </summary>
|
||||
DbTransaction TransactionCurrentThread { get; }
|
||||
/// <summary>
|
||||
/// 事务完成前预删除缓存
|
||||
/// </summary>
|
||||
/// <param name="keys"></param>
|
||||
void TransactionPreRemoveCache(params string[] keys);
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,108 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql {
|
||||
public interface ICache {
|
||||
|
||||
/// <summary>
|
||||
/// 缓存数据时序列化方法,若无设置则默认使用 Json.net
|
||||
/// </summary>
|
||||
Func<object, string> Serialize { get; set; }
|
||||
/// <summary>
|
||||
/// 获取缓存数据时反序列化方法,若无设置则默认使用 Json.net
|
||||
/// </summary>
|
||||
Func<string, Type, object> Deserialize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 缓存可序列化数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="data">可序列化数据</param>
|
||||
/// <param name="timeoutSeconds">缓存秒数,<=0时永久缓存</param>
|
||||
void Set<T>(string key, T data, int timeoutSeconds = 0);
|
||||
/// <summary>
|
||||
/// 循环或批量获取缓存数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
T Get<T>(string key);
|
||||
/// <summary>
|
||||
/// 循环或批量获取缓存数据
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
string Get(string key);
|
||||
/// <summary>
|
||||
/// 循环或批量删除缓存键
|
||||
/// </summary>
|
||||
/// <param name="keys">缓存键[数组]</param>
|
||||
void Remove(params string[] keys);
|
||||
/// <summary>
|
||||
/// 缓存壳
|
||||
/// </summary>
|
||||
/// <typeparam name="T">缓存类型</typeparam>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="timeoutSeconds">缓存秒数</param>
|
||||
/// <param name="getData">获取源数据的函数</param>
|
||||
/// <returns></returns>
|
||||
T Shell<T>(string key, int timeoutSeconds, Func<T> getData);
|
||||
/// <summary>
|
||||
/// 缓存壳(哈希表)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">缓存类型</typeparam>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="field">字段</param>
|
||||
/// <param name="timeoutSeconds">缓存秒数</param>
|
||||
/// <param name="getData">获取源数据的函数</param>
|
||||
/// <returns></returns>
|
||||
T Shell<T>(string key, string field, int timeoutSeconds, Func<T> getData);
|
||||
|
||||
/// <summary>
|
||||
/// 缓存可序列化数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="data">可序列化数据</param>
|
||||
/// <param name="timeoutSeconds">缓存秒数,<=0时永久缓存</param>
|
||||
Task SetAsync<T>(string key, T data, int timeoutSeconds = 0);
|
||||
/// <summary>
|
||||
/// 循环或批量获取缓存数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
Task<T> GetAsync<T>(string key);
|
||||
/// <summary>
|
||||
/// 循环或批量获取缓存数据
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> GetAsync(string key);
|
||||
/// <summary>
|
||||
/// 循环或批量删除缓存键
|
||||
/// </summary>
|
||||
/// <param name="keys">缓存键[数组]</param>
|
||||
Task RemoveAsync(params string[] keys);
|
||||
/// <summary>
|
||||
/// 缓存壳
|
||||
/// </summary>
|
||||
/// <typeparam name="T">缓存类型</typeparam>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="timeoutSeconds">缓存秒数</param>
|
||||
/// <param name="getDataAsync">获取源数据的函数</param>
|
||||
/// <returns></returns>
|
||||
Task<T> ShellAsync<T>(string key, int timeoutSeconds, Func<Task<T>> getDataAsync);
|
||||
/// <summary>
|
||||
/// 缓存壳(哈希表)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">缓存类型</typeparam>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="field">字段</param>
|
||||
/// <param name="timeoutSeconds">缓存秒数</param>
|
||||
/// <param name="getDataAsync">获取源数据的函数</param>
|
||||
/// <returns></returns>
|
||||
Task<T> ShellAsync<T>(string key, string field, int timeoutSeconds, Func<Task<T>> getDataAsync);
|
||||
}
|
||||
}
|
@ -87,10 +87,6 @@ public interface IFreeSql : IDisposable {
|
||||
/// <param name="timeout">超时,未执行完将自动提交</param>
|
||||
void Transaction(Action handler, TimeSpan timeout);
|
||||
|
||||
/// <summary>
|
||||
/// 缓存
|
||||
/// </summary>
|
||||
ICache Cache { get; }
|
||||
/// <summary>
|
||||
/// 数据库访问对象
|
||||
/// </summary>
|
||||
|
@ -10,17 +10,17 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace FreeSql.Internal {
|
||||
internal abstract class CommonExpression {
|
||||
public abstract class CommonExpression {
|
||||
|
||||
internal CommonUtils _common;
|
||||
internal CommonProvider.AdoProvider _ado => _adoPriv ?? (_adoPriv = _common._orm.Ado as CommonProvider.AdoProvider);
|
||||
public CommonUtils _common;
|
||||
public CommonProvider.AdoProvider _ado => _adoPriv ?? (_adoPriv = _common._orm.Ado as CommonProvider.AdoProvider);
|
||||
CommonProvider.AdoProvider _adoPriv;
|
||||
internal CommonExpression(CommonUtils common) {
|
||||
public CommonExpression(CommonUtils common) {
|
||||
_common = common;
|
||||
}
|
||||
|
||||
static ConcurrentDictionary<Type, PropertyInfo[]> _dicReadAnonymousFieldDtoPropertys = new ConcurrentDictionary<Type, PropertyInfo[]>();
|
||||
internal bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
|
||||
public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
|
||||
Func<ExpTSC> getTSC = () => new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where };
|
||||
switch (exp.NodeType) {
|
||||
case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString);
|
||||
@ -180,7 +180,7 @@ namespace FreeSql.Internal {
|
||||
if (index >= 0) field.Append(" as").Append(++index);
|
||||
return false;
|
||||
}
|
||||
internal object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead) {
|
||||
public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead) {
|
||||
if (parent.Childs.Any() == false) {
|
||||
if (notRead) {
|
||||
++index;
|
||||
@ -215,7 +215,7 @@ namespace FreeSql.Internal {
|
||||
return null;
|
||||
}
|
||||
|
||||
internal ColumnInfo SearchColumnByField(List<SelectTableInfo> _tables, TableInfo currentTable, string field) {
|
||||
public ColumnInfo SearchColumnByField(List<SelectTableInfo> _tables, TableInfo currentTable, string field) {
|
||||
if (_tables != null) {
|
||||
var testCol = _common.TrimQuoteSqlName(field).Split(new[] { '.' }, 2);
|
||||
if (testCol.Length == 2) {
|
||||
@ -232,11 +232,11 @@ namespace FreeSql.Internal {
|
||||
return null;
|
||||
}
|
||||
|
||||
internal string ExpressionSelectColumn_MemberAccess(List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, Expression exp, bool isQuoteName, Func<Expression[], string> getSelectGroupingMapString) {
|
||||
public string ExpressionSelectColumn_MemberAccess(List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, Expression exp, bool isQuoteName, Func<Expression[], string> getSelectGroupingMapString) {
|
||||
return ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = isQuoteName, isDisableDiyParse = false, style = ExpressionStyle.SelectColumns });
|
||||
}
|
||||
|
||||
internal string[] ExpressionSelectColumns_MemberAccess_New_NewArrayInit(List<SelectTableInfo> _tables, Expression exp, bool isQuoteName, Func<Expression[], string> getSelectGroupingMapString) {
|
||||
public string[] ExpressionSelectColumns_MemberAccess_New_NewArrayInit(List<SelectTableInfo> _tables, Expression exp, bool isQuoteName, Func<Expression[], string> getSelectGroupingMapString) {
|
||||
switch (exp?.NodeType) {
|
||||
case ExpressionType.Quote: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, getSelectGroupingMapString);
|
||||
case ExpressionType.Lambda: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as LambdaExpression)?.Body, isQuoteName, getSelectGroupingMapString);
|
||||
@ -276,7 +276,7 @@ namespace FreeSql.Internal {
|
||||
{ ExpressionType.Modulo, "%" },
|
||||
{ ExpressionType.Equal, "=" },
|
||||
};
|
||||
internal string ExpressionWhereLambdaNoneForeignObject(List<SelectTableInfo> _tables, TableInfo table, List<SelectColumnInfo> _selectColumnMap, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
|
||||
public string ExpressionWhereLambdaNoneForeignObject(List<SelectTableInfo> _tables, TableInfo table, List<SelectColumnInfo> _selectColumnMap, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
|
||||
var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table });
|
||||
if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool))
|
||||
return $"{sql} = {formatSql(true, null)}";
|
||||
@ -289,7 +289,7 @@ namespace FreeSql.Internal {
|
||||
}
|
||||
}
|
||||
|
||||
internal string ExpressionWhereLambda(List<SelectTableInfo> _tables, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
|
||||
public string ExpressionWhereLambda(List<SelectTableInfo> _tables, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
|
||||
var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where });
|
||||
if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool))
|
||||
return $"{sql} = {formatSql(true, null)}";
|
||||
@ -301,7 +301,7 @@ namespace FreeSql.Internal {
|
||||
default: return sql;
|
||||
}
|
||||
}
|
||||
internal void ExpressionJoinLambda(List<SelectTableInfo> _tables, SelectTableInfoType tbtype, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
|
||||
public void ExpressionJoinLambda(List<SelectTableInfo> _tables, SelectTableInfoType tbtype, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
|
||||
var tbidx = _tables.Count;
|
||||
var filter = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where });
|
||||
if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool))
|
||||
@ -333,7 +333,7 @@ namespace FreeSql.Internal {
|
||||
internal static ConcurrentDictionary<Type, PropertyInfo> _dicNullableValueProperty = new ConcurrentDictionary<Type, PropertyInfo>();
|
||||
static ConcurrentDictionary<Type, Expression> _dicFreeSqlGlobalExtensionsAsSelectExpression = new ConcurrentDictionary<Type, Expression>();
|
||||
|
||||
internal string ExpressionBinary(string oper, Expression leftExp, Expression rightExp, ExpTSC tsc) {
|
||||
public string ExpressionBinary(string oper, Expression leftExp, Expression rightExp, ExpTSC tsc) {
|
||||
switch (oper) {
|
||||
case "OR":
|
||||
case "|":
|
||||
@ -399,7 +399,7 @@ namespace FreeSql.Internal {
|
||||
tsc.mapType = null;
|
||||
return $"{left} {oper} {right}";
|
||||
}
|
||||
internal string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) {
|
||||
public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) {
|
||||
if (exp == null) return "";
|
||||
if (tsc.isDisableDiyParse == false && _common._orm.Aop.ParseExpression != null) {
|
||||
var args = new Aop.ParseExpressionEventArgs(exp, ukexp => ExpressionLambdaToSql(exp, tsc.CloneDisableDiyParse()));
|
||||
@ -882,20 +882,20 @@ namespace FreeSql.Internal {
|
||||
return ExpressionBinary(tryoper, expBinary.Left, expBinary.Right, tsc);
|
||||
}
|
||||
|
||||
internal abstract string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc);
|
||||
internal abstract string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc);
|
||||
internal abstract string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc);
|
||||
internal abstract string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc);
|
||||
internal abstract string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc);
|
||||
internal abstract string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc);
|
||||
internal abstract string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc);
|
||||
internal abstract string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc);
|
||||
internal abstract string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc);
|
||||
public abstract string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc);
|
||||
public abstract string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc);
|
||||
public abstract string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc);
|
||||
public abstract string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc);
|
||||
public abstract string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc);
|
||||
public abstract string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc);
|
||||
public abstract string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc);
|
||||
public abstract string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc);
|
||||
public abstract string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc);
|
||||
|
||||
internal enum ExpressionStyle {
|
||||
public enum ExpressionStyle {
|
||||
Where, AsSelect, SelectColumns
|
||||
}
|
||||
internal class ExpTSC {
|
||||
public class ExpTSC {
|
||||
public List<SelectTableInfo> _tables { get; set; }
|
||||
public List<SelectColumnInfo> _selectColumnMap { get; set; }
|
||||
public Func<Expression[], string> getSelectGroupingMapString { get; set; }
|
||||
@ -932,7 +932,7 @@ namespace FreeSql.Internal {
|
||||
}
|
||||
}
|
||||
|
||||
internal string formatSql(object obj, Type mapType) {
|
||||
public string formatSql(object obj, Type mapType) {
|
||||
return string.Concat(_ado.AddslashesProcessParam(obj, mapType));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SafeObjectPool;
|
||||
using SafeObjectPool;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
@ -11,7 +10,7 @@ using System.Text;
|
||||
using System.Reflection;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
abstract partial class AdoProvider : IAdo, IDisposable {
|
||||
public abstract partial class AdoProvider : IAdo, IDisposable {
|
||||
|
||||
protected abstract void ReturnConnection(ObjectPool<DbConnection> pool, Object<DbConnection> conn, Exception ex);
|
||||
protected abstract DbCommand CreateCommand();
|
||||
@ -24,16 +23,12 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
public ObjectPool<DbConnection> MasterPool { get; protected set; }
|
||||
public List<ObjectPool<DbConnection>> SlavePools { get; } = new List<ObjectPool<DbConnection>>();
|
||||
public DataType DataType { get; }
|
||||
protected ICache _cache { get; set; }
|
||||
protected ILogger _log { get; set; }
|
||||
protected CommonUtils _util { get; set; }
|
||||
protected int slaveUnavailables = 0;
|
||||
private object slaveLock = new object();
|
||||
private Random slaveRandom = new Random();
|
||||
|
||||
public AdoProvider(ICache cache, ILogger log, DataType dataType) {
|
||||
this._cache = cache;
|
||||
this._log = log;
|
||||
public AdoProvider(DataType dataType) {
|
||||
this.DataType = dataType;
|
||||
}
|
||||
|
||||
@ -43,7 +38,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
if (IsTracePerformance) {
|
||||
TimeSpan ts = DateTime.Now.Subtract(dt);
|
||||
if (e == null && ts.TotalMilliseconds > 100)
|
||||
_log.LogWarning(logtxt.Insert(0, $"{pool?.Policy.Name}(执行SQL)语句耗时过长{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString());
|
||||
Trace.WriteLine(logtxt.Insert(0, $"{pool?.Policy.Name}(执行SQL)语句耗时过长{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString());
|
||||
else
|
||||
logtxt.Insert(0, $"{pool?.Policy.Name}(执行SQL)耗时{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString();
|
||||
}
|
||||
@ -59,7 +54,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
log.Append(parm.ParameterName.PadRight(20, ' ')).Append(" = ").Append((parm.Value ?? DBNull.Value) == DBNull.Value ? "NULL" : parm.Value).Append("\r\n");
|
||||
|
||||
log.Append(e.Message);
|
||||
_log.LogError(log.ToString());
|
||||
Trace.WriteLine(log.ToString());
|
||||
|
||||
if (cmd.Transaction != null) {
|
||||
var curTran = TransactionCurrentThread;
|
||||
|
@ -1,9 +1,8 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using SafeObjectPool;
|
||||
using SafeObjectPool;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
@ -29,24 +28,6 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
public DbTransaction TransactionCurrentThread => _trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var conn) && conn.Transaction?.Connection != null ? conn.Transaction : null;
|
||||
|
||||
private Dictionary<int, List<string>> _preRemoveKeys = new Dictionary<int, List<string>>();
|
||||
private object _preRemoveKeys_lock = new object();
|
||||
public string[] PreRemove(params string[] key) {
|
||||
var tid = Thread.CurrentThread.ManagedThreadId;
|
||||
List<string> keys = null;
|
||||
if (key == null || key.Any() == false) return _preRemoveKeys.TryGetValue(tid, out keys) ? keys.ToArray() : new string[0];
|
||||
_log.LogDebug($"线程{tid}事务预删除 {JsonConvert.SerializeObject(key)}");
|
||||
if (_preRemoveKeys.TryGetValue(tid, out keys) == false)
|
||||
lock (_preRemoveKeys_lock)
|
||||
if (_preRemoveKeys.TryGetValue(tid, out keys) == false) {
|
||||
_preRemoveKeys.Add(tid, keys = new List<string>(key));
|
||||
return key;
|
||||
}
|
||||
keys.AddRange(key);
|
||||
return keys.ToArray();
|
||||
}
|
||||
public void TransactionPreRemoveCache(params string[] key) => PreRemove(key);
|
||||
|
||||
public void BeginTransaction(TimeSpan timeout) {
|
||||
if (TransactionCurrentThread != null) return;
|
||||
|
||||
@ -58,7 +39,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
conn = MasterPool.Get();
|
||||
tran = new Transaction2(conn, conn.Value.BeginTransaction(), timeout);
|
||||
} catch(Exception ex) {
|
||||
_log.LogError($"数据库出错(开启事务){ex.Message} \r\n{ex.StackTrace}");
|
||||
Trace.WriteLine($"数据库出错(开启事务){ex.Message} \r\n{ex.StackTrace}");
|
||||
MasterPool.Return(conn);
|
||||
throw ex;
|
||||
}
|
||||
@ -84,22 +65,15 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
if (_trans.ContainsKey(tran.Conn.LastGetThreadId))
|
||||
_trans.Remove(tran.Conn.LastGetThreadId);
|
||||
|
||||
var removeKeys = PreRemove();
|
||||
if (_preRemoveKeys.ContainsKey(tran.Conn.LastGetThreadId))
|
||||
lock (_preRemoveKeys_lock)
|
||||
if (_preRemoveKeys.ContainsKey(tran.Conn.LastGetThreadId))
|
||||
_preRemoveKeys.Remove(tran.Conn.LastGetThreadId);
|
||||
|
||||
Exception ex = null;
|
||||
var f001 = isCommit ? "提交" : "回滚";
|
||||
try {
|
||||
_log.LogDebug($"线程{tran.Conn.LastGetThreadId}事务{f001},批量删除缓存key {Newtonsoft.Json.JsonConvert.SerializeObject(removeKeys)}");
|
||||
_cache.Remove(removeKeys);
|
||||
Trace.WriteLine($"线程{tran.Conn.LastGetThreadId}事务{f001}");
|
||||
if (isCommit) tran.Transaction.Commit();
|
||||
else tran.Transaction.Rollback();
|
||||
} catch (Exception ex2) {
|
||||
ex = ex2;
|
||||
_log.LogError($"数据库出错({f001}事务):{ex.Message} {ex.StackTrace}");
|
||||
Trace.WriteLine($"数据库出错({f001}事务):{ex.Message} {ex.StackTrace}");
|
||||
} finally {
|
||||
ReturnConnection(MasterPool, tran.Conn, ex); //MasterPool.Return(tran.Conn, ex);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
class AopProvider : IAop {
|
||||
public class AopProvider : IAop {
|
||||
public EventHandler<Aop.ToListEventArgs> ToList { get; set; }
|
||||
public EventHandler<Aop.WhereEventArgs> Where { get; set; }
|
||||
public EventHandler<Aop.ParseExpressionEventArgs> ParseExpression { get; set; }
|
||||
|
@ -1,186 +0,0 @@
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
class CacheProvider : ICache, IDisposable {
|
||||
|
||||
public IDistributedCache Cache { get; private set; }
|
||||
private bool CacheSupportMultiRemove = false;
|
||||
private static DateTime dt1970 = new DateTime(1970, 1, 1);
|
||||
|
||||
public CacheProvider(IDistributedCache cache, ILogger log) {
|
||||
if (cache == null) cache = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions { }));
|
||||
Cache = cache;
|
||||
var key1 = $"testCacheSupportMultiRemoveFreeSql{Guid.NewGuid().ToString("N")}";
|
||||
var key2 = $"testCacheSupportMultiRemoveFreeSql{Guid.NewGuid().ToString("N")}";
|
||||
Cache.Set(key1, new byte[] { 65 });
|
||||
Cache.Set(key2, new byte[] { 65 });
|
||||
try { Cache.Remove($"{key1}|{key2}"); } catch { } // redis-cluster 不允许执行 multi keys 命令
|
||||
CacheSupportMultiRemove = Cache.Get(key1) == null && cache.Get(key2) == null;
|
||||
if (CacheSupportMultiRemove == false) {
|
||||
//log.LogWarning("FreeSql Warning: 低性能, IDistributedCache 没实现批量删除缓存 Cache.Remove(\"key1|key2\").");
|
||||
Remove(key1, key2);
|
||||
}
|
||||
}
|
||||
|
||||
~CacheProvider() {
|
||||
this.Dispose();
|
||||
}
|
||||
bool _isdisposed = false;
|
||||
public void Dispose() {
|
||||
if (_isdisposed) return;
|
||||
|
||||
Cache = null;
|
||||
}
|
||||
|
||||
public Func<object, string> Serialize { get; set; }
|
||||
public Func<string, Type, object> Deserialize { get; set; }
|
||||
|
||||
Func<JsonSerializerSettings> JsonSerializerSettings = () => {
|
||||
var st = new JsonSerializerSettings();
|
||||
st.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
|
||||
st.DateFormatHandling = DateFormatHandling.IsoDateFormat;
|
||||
st.DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
|
||||
return st;
|
||||
};
|
||||
string SerializeObject(object value) {
|
||||
if (Serialize != null) return Serialize(value);
|
||||
return JsonConvert.SerializeObject(value, this.JsonSerializerSettings());
|
||||
}
|
||||
T DeserializeObject<T>(string value) {
|
||||
if (Deserialize != null) return (T) Deserialize(value, typeof(T));
|
||||
return JsonConvert.DeserializeObject<T>(value, this.JsonSerializerSettings());
|
||||
}
|
||||
|
||||
public void Set<T>(string key, T data, int timeoutSeconds = 0) {
|
||||
if (string.IsNullOrEmpty(key)) return;
|
||||
Cache.Set(key, Encoding.UTF8.GetBytes(this.SerializeObject(data)), new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(timeoutSeconds) });
|
||||
}
|
||||
public T Get<T>(string key) {
|
||||
if (string.IsNullOrEmpty(key)) return default(T);
|
||||
var value = Cache.Get(key);
|
||||
if (value == null) return default(T);
|
||||
return this.DeserializeObject<T>(Encoding.UTF8.GetString(value));
|
||||
}
|
||||
public string Get(string key) {
|
||||
if (string.IsNullOrEmpty(key)) return null;
|
||||
var value = Cache.Get(key);
|
||||
if (value == null) return null;
|
||||
return Encoding.UTF8.GetString(value);
|
||||
}
|
||||
|
||||
async public Task SetAsync<T>(string key, T data, int timeoutSeconds = 0) {
|
||||
if (string.IsNullOrEmpty(key)) return;
|
||||
await Cache.SetAsync(key, Encoding.UTF8.GetBytes(this.SerializeObject(data)), new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(timeoutSeconds) });
|
||||
}
|
||||
async public Task<T> GetAsync<T>(string key) {
|
||||
if (string.IsNullOrEmpty(key)) return default(T);
|
||||
var value = await Cache.GetAsync(key);
|
||||
if (value == null) return default(T);
|
||||
return this.DeserializeObject<T>(Encoding.UTF8.GetString(value));
|
||||
}
|
||||
async public Task<string> GetAsync(string key) {
|
||||
if (string.IsNullOrEmpty(key)) return null;
|
||||
var value = await Cache.GetAsync(key);
|
||||
if (value == null) return null;
|
||||
return Encoding.UTF8.GetString(value);
|
||||
}
|
||||
|
||||
public void Remove(params string[] keys) {
|
||||
if (keys == null || keys.Length == 0) return;
|
||||
var keysDistinct = keys.Distinct();
|
||||
if (CacheSupportMultiRemove) Cache.Remove(string.Join("|", keysDistinct));
|
||||
else foreach (var key in keysDistinct) Cache.Remove(key);
|
||||
}
|
||||
|
||||
async public Task RemoveAsync(params string[] keys) {
|
||||
if (keys == null || keys.Length == 0) return;
|
||||
var keysDistinct = keys.Distinct();
|
||||
if (CacheSupportMultiRemove) await Cache.RemoveAsync(string.Join("|", keysDistinct));
|
||||
else foreach (var key in keysDistinct) await Cache.RemoveAsync(key);
|
||||
}
|
||||
|
||||
public T Shell<T>(string key, int timeoutSeconds, Func<T> getData) {
|
||||
if (timeoutSeconds <= 0) return getData();
|
||||
if (Cache == null) throw new Exception("缓存实现 IDistributedCache 为 null");
|
||||
var cacheValue = Cache.Get(key);
|
||||
if (cacheValue != null) {
|
||||
try {
|
||||
var txt = Encoding.UTF8.GetString(cacheValue);
|
||||
return DeserializeObject<T>(txt);
|
||||
} catch {
|
||||
Cache.Remove(key);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
var ret = getData();
|
||||
Cache.Set(key, Encoding.UTF8.GetBytes(SerializeObject(ret)), new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(timeoutSeconds) });
|
||||
return ret;
|
||||
}
|
||||
|
||||
public T Shell<T>(string key, string field, int timeoutSeconds, Func<T> getData) {
|
||||
if (timeoutSeconds <= 0) return getData();
|
||||
if (Cache == null) throw new Exception("缓存实现 IDistributedCache 为 null");
|
||||
var hashkey = $"{key}:{field}";
|
||||
var cacheValue = Cache.Get(hashkey);
|
||||
if (cacheValue != null) {
|
||||
try {
|
||||
var txt = Encoding.UTF8.GetString(cacheValue);
|
||||
var value = DeserializeObject<(T, long)>(txt);
|
||||
if (DateTime.Now.Subtract(dt1970.AddSeconds(value.Item2)).TotalSeconds <= timeoutSeconds) return value.Item1;
|
||||
} catch {
|
||||
Cache.Remove(hashkey);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
var ret = (getData(), (long) DateTime.Now.Subtract(dt1970).TotalSeconds);
|
||||
Cache.Set(hashkey, Encoding.UTF8.GetBytes(SerializeObject(ret)));
|
||||
return ret.Item1;
|
||||
}
|
||||
|
||||
async public Task<T> ShellAsync<T>(string key, int timeoutSeconds, Func<Task<T>> getDataAsync) {
|
||||
if (timeoutSeconds <= 0) return await getDataAsync();
|
||||
if (Cache == null) throw new Exception("缓存实现 IDistributedCache 为 null");
|
||||
var cacheValue = await Cache.GetAsync(key);
|
||||
if (cacheValue != null) {
|
||||
try {
|
||||
var txt = Encoding.UTF8.GetString(cacheValue);
|
||||
return DeserializeObject<T>(txt);
|
||||
} catch {
|
||||
await Cache.RemoveAsync(key);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
var ret = await getDataAsync();
|
||||
await Cache.SetAsync(key, Encoding.UTF8.GetBytes(SerializeObject(ret)), new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(timeoutSeconds) });
|
||||
return ret;
|
||||
}
|
||||
|
||||
async public Task<T> ShellAsync<T>(string key, string field, int timeoutSeconds, Func<Task<T>> getDataAsync) {
|
||||
if (timeoutSeconds <= 0) return await getDataAsync();
|
||||
if (Cache == null) throw new Exception("缓存实现 IDistributedCache 为 null");
|
||||
var hashkey = $"{key}:{field}";
|
||||
var cacheValue = await Cache.GetAsync(hashkey);
|
||||
if (cacheValue != null) {
|
||||
try {
|
||||
var txt = Encoding.UTF8.GetString(cacheValue);
|
||||
var value = DeserializeObject<(T, long)>(txt);
|
||||
if (DateTime.Now.Subtract(dt1970.AddSeconds(value.Item2)).TotalSeconds <= timeoutSeconds) return value.Item1;
|
||||
} catch {
|
||||
await Cache.RemoveAsync(hashkey);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
var ret = (await getDataAsync(), (long) DateTime.Now.Subtract(dt1970).TotalSeconds);
|
||||
await Cache.SetAsync(hashkey, Encoding.UTF8.GetBytes(SerializeObject(ret)));
|
||||
return ret.Item1;
|
||||
}
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract partial class DeleteProvider<T1> : IDelete<T1> where T1 : class {
|
||||
public abstract partial class DeleteProvider<T1> : IDelete<T1> where T1 : class {
|
||||
protected IFreeSql _orm;
|
||||
protected CommonUtils _commonUtils;
|
||||
protected CommonExpression _commonExpression;
|
||||
|
@ -11,7 +11,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract partial class InsertProvider<T1> : IInsert<T1> where T1 : class {
|
||||
public abstract partial class InsertProvider<T1> : IInsert<T1> where T1 : class {
|
||||
protected IFreeSql _orm;
|
||||
protected CommonUtils _commonUtils;
|
||||
protected CommonExpression _commonExpression;
|
||||
@ -69,7 +69,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
}
|
||||
|
||||
#region 参数化数据限制,或values数量限制
|
||||
internal List<T1>[] SplitSource(int valuesLimit, int parameterLimit) {
|
||||
protected List<T1>[] SplitSource(int valuesLimit, int parameterLimit) {
|
||||
valuesLimit = valuesLimit - 1;
|
||||
parameterLimit = parameterLimit - 1;
|
||||
if (_source == null || _source.Any() == false) return new List<T1>[0];
|
||||
@ -101,7 +101,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
internal int SplitExecuteAffrows(int valuesLimit, int parameterLimit) {
|
||||
protected int SplitExecuteAffrows(int valuesLimit, int parameterLimit) {
|
||||
var ss = SplitSource(valuesLimit, parameterLimit);
|
||||
var ret = 0;
|
||||
if (ss.Any() == false) {
|
||||
@ -137,7 +137,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
ClearData();
|
||||
return ret;
|
||||
}
|
||||
async internal Task<int> SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) {
|
||||
async protected Task<int> SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) {
|
||||
var ss = SplitSource(valuesLimit, parameterLimit);
|
||||
var ret = 0;
|
||||
if (ss.Any() == false) {
|
||||
@ -173,7 +173,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
ClearData();
|
||||
return ret;
|
||||
}
|
||||
internal long SplitExecuteIdentity(int valuesLimit, int parameterLimit) {
|
||||
protected long SplitExecuteIdentity(int valuesLimit, int parameterLimit) {
|
||||
var ss = SplitSource(valuesLimit, parameterLimit);
|
||||
long ret = 0;
|
||||
if (ss.Any() == false) {
|
||||
@ -211,7 +211,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
ClearData();
|
||||
return ret;
|
||||
}
|
||||
async internal Task<long> SplitExecuteIdentityAsync(int valuesLimit, int parameterLimit) {
|
||||
async protected Task<long> SplitExecuteIdentityAsync(int valuesLimit, int parameterLimit) {
|
||||
var ss = SplitSource(valuesLimit, parameterLimit);
|
||||
long ret = 0;
|
||||
if (ss.Any() == false) {
|
||||
@ -249,7 +249,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
ClearData();
|
||||
return ret;
|
||||
}
|
||||
internal List<T1> SplitExecuteInserted(int valuesLimit, int parameterLimit) {
|
||||
protected List<T1> SplitExecuteInserted(int valuesLimit, int parameterLimit) {
|
||||
var ss = SplitSource(valuesLimit, parameterLimit);
|
||||
var ret = new List<T1>();
|
||||
if (ss.Any() == false) {
|
||||
@ -285,7 +285,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
ClearData();
|
||||
return ret;
|
||||
}
|
||||
async internal Task<List<T1>> SplitExecuteInsertedAsync(int valuesLimit, int parameterLimit) {
|
||||
async protected Task<List<T1>> SplitExecuteInsertedAsync(int valuesLimit, int parameterLimit) {
|
||||
var ss = SplitSource(valuesLimit, parameterLimit);
|
||||
var ret = new List<T1>();
|
||||
if (ss.Any() == false) {
|
||||
@ -323,7 +323,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
}
|
||||
#endregion
|
||||
|
||||
internal int RawExecuteAffrows() {
|
||||
protected int RawExecuteAffrows() {
|
||||
var sql = ToSql();
|
||||
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
@ -341,7 +341,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
this.ClearData();
|
||||
return affrows;
|
||||
}
|
||||
async internal Task<int> RawExecuteAffrowsAsync() {
|
||||
async protected Task<int> RawExecuteAffrowsAsync() {
|
||||
var sql = ToSql();
|
||||
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
@ -359,10 +359,10 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
this.ClearData();
|
||||
return affrows;
|
||||
}
|
||||
internal abstract long RawExecuteIdentity();
|
||||
internal abstract Task<long> RawExecuteIdentityAsync();
|
||||
internal abstract List<T1> RawExecuteInserted();
|
||||
internal abstract Task<List<T1>> RawExecuteInsertedAsync();
|
||||
protected abstract long RawExecuteIdentity();
|
||||
protected abstract Task<long> RawExecuteIdentityAsync();
|
||||
protected abstract List<T1> RawExecuteInserted();
|
||||
protected abstract Task<List<T1>> RawExecuteInsertedAsync();
|
||||
|
||||
public abstract int ExecuteAffrows();
|
||||
public abstract Task<int> ExecuteAffrowsAsync();
|
||||
|
@ -14,16 +14,15 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract class Select0Provider<TSelect, T1> : ISelect0<TSelect, T1> where TSelect : class where T1 : class {
|
||||
public abstract class Select0Provider<TSelect, T1> : ISelect0<TSelect, T1> where TSelect : class where T1 : class {
|
||||
|
||||
protected int _limit, _skip;
|
||||
protected string _select = "SELECT ", _orderby, _groupby, _having;
|
||||
protected StringBuilder _where = new StringBuilder();
|
||||
protected List<DbParameter> _params = new List<DbParameter>();
|
||||
internal List<SelectTableInfo> _tables = new List<SelectTableInfo>();
|
||||
protected List<SelectTableInfo> _tables = new List<SelectTableInfo>();
|
||||
protected List<Func<Type, string, string>> _tableRules = new List<Func<Type, string, string>>();
|
||||
protected StringBuilder _join = new StringBuilder();
|
||||
protected (int seconds, string key) _cache = (0, null);
|
||||
protected IFreeSql _orm;
|
||||
protected CommonUtils _commonUtils;
|
||||
protected CommonExpression _commonExpression;
|
||||
@ -34,7 +33,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
protected bool _distinct;
|
||||
protected Expression _selectExpression;
|
||||
|
||||
internal static void CopyData(Select0Provider<TSelect, T1> from, object to, ReadOnlyCollection<ParameterExpression> lambParms) {
|
||||
public static void CopyData(Select0Provider<TSelect, T1> from, object to, ReadOnlyCollection<ParameterExpression> lambParms) {
|
||||
var toType = to?.GetType();
|
||||
if (toType == null) return;
|
||||
toType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._limit);
|
||||
@ -63,7 +62,6 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
}
|
||||
toType.GetField("_tableRules", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._tableRules);
|
||||
toType.GetField("_join", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, new StringBuilder().Append(from._join.ToString()));
|
||||
toType.GetField("_cache", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._cache);
|
||||
//toType.GetField("_orm", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._orm);
|
||||
//toType.GetField("_commonUtils", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._commonUtils);
|
||||
//toType.GetField("_commonExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._commonExpression);
|
||||
@ -109,10 +107,6 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
return (await this.ToListAsync<int>("1")).FirstOrDefault() == 1;
|
||||
}
|
||||
|
||||
public TSelect Caching(int seconds, string key = null) {
|
||||
_cache = (seconds, key);
|
||||
return this as TSelect;
|
||||
}
|
||||
public long Count() => this.ToList<int>("count(1)").FirstOrDefault();
|
||||
async public Task<long> CountAsync() => (await this.ToListAsync<int>("count(1)")).FirstOrDefault();
|
||||
|
||||
@ -220,166 +214,142 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
public DataTable ToDataTable(string field = null) {
|
||||
var sql = this.ToSql(field);
|
||||
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = sql;
|
||||
|
||||
return _orm.Cache.Shell(_cache.key, _cache.seconds, () => {
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
DataTable ret = null;
|
||||
Exception exception = null;
|
||||
try {
|
||||
ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
DataTable ret = null;
|
||||
Exception exception = null;
|
||||
try {
|
||||
ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
public Task<DataTable> ToDataTableAsync(string field = null) {
|
||||
async public Task<DataTable> ToDataTableAsync(string field = null) {
|
||||
var sql = this.ToSql(field);
|
||||
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = sql;
|
||||
|
||||
return _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => {
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
DataTable ret = null;
|
||||
Exception exception = null;
|
||||
try {
|
||||
ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
DataTable ret = null;
|
||||
Exception exception = null;
|
||||
try {
|
||||
ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<TTuple> ToList<TTuple>(string field) {
|
||||
var sql = this.ToSql(field);
|
||||
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = sql;
|
||||
|
||||
return _orm.Cache.Shell(_cache.key, _cache.seconds, () => {
|
||||
var type = typeof(TTuple);
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
var ret = new List<TTuple>();
|
||||
var flagStr = $"ToListField:{field}";
|
||||
Exception exception = null;
|
||||
try {
|
||||
_orm.Ado.ExecuteReader(_connection, _transaction, dr => {
|
||||
var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils);
|
||||
ret.Add((TTuple)read.Value);
|
||||
}, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
var type = typeof(TTuple);
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
var ret = new List<TTuple>();
|
||||
var flagStr = $"ToListField:{field}";
|
||||
Exception exception = null;
|
||||
try {
|
||||
_orm.Ado.ExecuteReader(_connection, _transaction, dr => {
|
||||
var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils);
|
||||
ret.Add((TTuple)read.Value);
|
||||
}, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
public Task<List<TTuple>> ToListAsync<TTuple>(string field) {
|
||||
async public Task<List<TTuple>> ToListAsync<TTuple>(string field) {
|
||||
var sql = this.ToSql(field);
|
||||
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = sql;
|
||||
|
||||
return _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => {
|
||||
var type = typeof(TTuple);
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
var ret = new List<TTuple>();
|
||||
var flagStr = $"ToListField:{field}";
|
||||
Exception exception = null;
|
||||
try {
|
||||
await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => {
|
||||
var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils);
|
||||
ret.Add((TTuple)read.Value);
|
||||
return Task.CompletedTask;
|
||||
}, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
var type = typeof(TTuple);
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
var ret = new List<TTuple>();
|
||||
var flagStr = $"ToListField:{field}";
|
||||
Exception exception = null;
|
||||
try {
|
||||
await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => {
|
||||
var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, dr, 0, _commonUtils);
|
||||
ret.Add((TTuple)read.Value);
|
||||
return Task.CompletedTask;
|
||||
}, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
internal List<T1> ToListAfPrivate(string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List<object> retlist)[] otherData) {
|
||||
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
|
||||
|
||||
return _orm.Cache.Shell(_cache.key, _cache.seconds, () => {
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
var ret = new List<T1>();
|
||||
Exception exception = null;
|
||||
try {
|
||||
_orm.Ado.ExecuteReader(_connection, _transaction, dr => {
|
||||
ret.Add(af.Read(_orm, dr));
|
||||
if (otherData != null) {
|
||||
var idx = af.FieldCount - 1;
|
||||
foreach (var other in otherData)
|
||||
other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false));
|
||||
}
|
||||
}, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
while (_includeToList.Any()) _includeToList.Dequeue()?.Invoke(ret);
|
||||
_orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret));
|
||||
_trackToList?.Invoke(ret);
|
||||
return ret;
|
||||
});
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
var ret = new List<T1>();
|
||||
Exception exception = null;
|
||||
try {
|
||||
_orm.Ado.ExecuteReader(_connection, _transaction, dr => {
|
||||
ret.Add(af.Read(_orm, dr));
|
||||
if (otherData != null) {
|
||||
var idx = af.FieldCount - 1;
|
||||
foreach (var other in otherData)
|
||||
other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false));
|
||||
}
|
||||
}, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
while (_includeToList.Any()) _includeToList.Dequeue()?.Invoke(ret);
|
||||
_orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret));
|
||||
_trackToList?.Invoke(ret);
|
||||
return ret;
|
||||
}
|
||||
async internal Task<List<T1>> ToListAfPrivateAsync(string sql, GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List<object> retlist)[] otherData) {
|
||||
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
|
||||
|
||||
return await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => {
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
var ret = new List<T1>();
|
||||
Exception exception = null;
|
||||
try {
|
||||
await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => {
|
||||
ret.Add(af.Read(_orm, dr));
|
||||
if (otherData != null) {
|
||||
var idx = af.FieldCount - 1;
|
||||
foreach (var other in otherData)
|
||||
other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false));
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
while (_includeToList.Any()) _includeToList.Dequeue()?.Invoke(ret);
|
||||
_orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret));
|
||||
_trackToList?.Invoke(ret);
|
||||
return ret;
|
||||
});
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
var ret = new List<T1>();
|
||||
Exception exception = null;
|
||||
try {
|
||||
await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => {
|
||||
ret.Add(af.Read(_orm, dr));
|
||||
if (otherData != null) {
|
||||
var idx = af.FieldCount - 1;
|
||||
foreach (var other in otherData)
|
||||
other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false));
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
while (_includeToList.Any()) _includeToList.Dequeue()?.Invoke(ret);
|
||||
_orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret));
|
||||
_trackToList?.Invoke(ret);
|
||||
return ret;
|
||||
}
|
||||
internal List<T1> ToListPrivate(GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List<object> retlist)[] otherData) {
|
||||
string sql = null;
|
||||
@ -427,60 +397,52 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
protected List<TReturn> ToListMapReader<TReturn>((ReadAnonymousTypeInfo map, string field) af) {
|
||||
var sql = this.ToSql(af.field);
|
||||
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
|
||||
|
||||
return _orm.Cache.Shell(_cache.key, _cache.seconds, () => {
|
||||
var type = typeof(TReturn);
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
var ret = new List<TReturn>();
|
||||
Exception exception = null;
|
||||
try {
|
||||
_orm.Ado.ExecuteReader(_connection, _transaction, dr => {
|
||||
var index = -1;
|
||||
ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false));
|
||||
}, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
_orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret));
|
||||
_trackToList?.Invoke(ret);
|
||||
return ret;
|
||||
});
|
||||
var type = typeof(TReturn);
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
var ret = new List<TReturn>();
|
||||
Exception exception = null;
|
||||
try {
|
||||
_orm.Ado.ExecuteReader(_connection, _transaction, dr => {
|
||||
var index = -1;
|
||||
ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false));
|
||||
}, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
_orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret));
|
||||
_trackToList?.Invoke(ret);
|
||||
return ret;
|
||||
}
|
||||
async protected Task<List<TReturn>> ToListMapReaderAsync<TReturn>((ReadAnonymousTypeInfo map, string field) af) {
|
||||
var sql = this.ToSql(af.field);
|
||||
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
|
||||
|
||||
return await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => {
|
||||
var type = typeof(TReturn);
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
var ret = new List<TReturn>();
|
||||
Exception exception = null;
|
||||
try {
|
||||
await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => {
|
||||
var index = -1;
|
||||
ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false));
|
||||
return Task.CompletedTask;
|
||||
}, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
_orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret));
|
||||
_trackToList?.Invoke(ret);
|
||||
return ret;
|
||||
});
|
||||
var type = typeof(TReturn);
|
||||
var dbParms = _params.ToArray();
|
||||
var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, Aop.CurdType.Select, sql, dbParms);
|
||||
_orm.Aop.CurdBefore?.Invoke(this, before);
|
||||
var ret = new List<TReturn>();
|
||||
Exception exception = null;
|
||||
try {
|
||||
await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => {
|
||||
var index = -1;
|
||||
ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false));
|
||||
return Task.CompletedTask;
|
||||
}, CommandType.Text, sql, dbParms);
|
||||
} catch (Exception ex) {
|
||||
exception = ex;
|
||||
throw ex;
|
||||
} finally {
|
||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||
}
|
||||
_orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret));
|
||||
_trackToList?.Invoke(ret);
|
||||
return ret;
|
||||
}
|
||||
protected (ReadAnonymousTypeInfo map, string field) GetExpressionField(Expression newexp) {
|
||||
var map = new ReadAnonymousTypeInfo();
|
||||
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract class Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : Select0Provider<ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, T1>, ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>
|
||||
public abstract class Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : Select0Provider<ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, T1>, ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>
|
||||
where T1 : class
|
||||
where T2 : class
|
||||
where T3 : class
|
||||
|
@ -16,7 +16,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract class Select1Provider<T1> : Select0Provider<ISelect<T1>, T1>, ISelect<T1>
|
||||
public abstract class Select1Provider<T1> : Select0Provider<ISelect<T1>, T1>, ISelect<T1>
|
||||
where T1 : class {
|
||||
public Select1Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) {
|
||||
|
||||
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract class Select2Provider<T1, T2> : Select0Provider<ISelect<T1, T2>, T1>, ISelect<T1, T2>
|
||||
public abstract class Select2Provider<T1, T2> : Select0Provider<ISelect<T1, T2>, T1>, ISelect<T1, T2>
|
||||
where T1 : class
|
||||
where T2 : class {
|
||||
|
||||
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract class Select3Provider<T1, T2, T3> : Select0Provider<ISelect<T1, T2, T3>, T1>, ISelect<T1, T2, T3>
|
||||
public abstract class Select3Provider<T1, T2, T3> : Select0Provider<ISelect<T1, T2, T3>, T1>, ISelect<T1, T2, T3>
|
||||
where T1 : class
|
||||
where T2 : class
|
||||
where T3 : class {
|
||||
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract class Select4Provider<T1, T2, T3, T4> : Select0Provider<ISelect<T1, T2, T3, T4>, T1>, ISelect<T1, T2, T3, T4>
|
||||
public abstract class Select4Provider<T1, T2, T3, T4> : Select0Provider<ISelect<T1, T2, T3, T4>, T1>, ISelect<T1, T2, T3, T4>
|
||||
where T1 : class
|
||||
where T2 : class
|
||||
where T3 : class
|
||||
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract class Select5Provider<T1, T2, T3, T4, T5> : Select0Provider<ISelect<T1, T2, T3, T4, T5>, T1>, ISelect<T1, T2, T3, T4, T5>
|
||||
public abstract class Select5Provider<T1, T2, T3, T4, T5> : Select0Provider<ISelect<T1, T2, T3, T4, T5>, T1>, ISelect<T1, T2, T3, T4, T5>
|
||||
where T1 : class
|
||||
where T2 : class
|
||||
where T3 : class
|
||||
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract class Select6Provider<T1, T2, T3, T4, T5, T6> : Select0Provider<ISelect<T1, T2, T3, T4, T5, T6>, T1>, ISelect<T1, T2, T3, T4, T5, T6>
|
||||
public abstract class Select6Provider<T1, T2, T3, T4, T5, T6> : Select0Provider<ISelect<T1, T2, T3, T4, T5, T6>, T1>, ISelect<T1, T2, T3, T4, T5, T6>
|
||||
where T1 : class
|
||||
where T2 : class
|
||||
where T3 : class
|
||||
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract class Select7Provider<T1, T2, T3, T4, T5, T6, T7> : Select0Provider<ISelect<T1, T2, T3, T4, T5, T6, T7>, T1>, ISelect<T1, T2, T3, T4, T5, T6, T7>
|
||||
public abstract class Select7Provider<T1, T2, T3, T4, T5, T6, T7> : Select0Provider<ISelect<T1, T2, T3, T4, T5, T6, T7>, T1>, ISelect<T1, T2, T3, T4, T5, T6, T7>
|
||||
where T1 : class
|
||||
where T2 : class
|
||||
where T3 : class
|
||||
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract class Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> : Select0Provider<ISelect<T1, T2, T3, T4, T5, T6, T7, T8>, T1>, ISelect<T1, T2, T3, T4, T5, T6, T7, T8>
|
||||
public abstract class Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> : Select0Provider<ISelect<T1, T2, T3, T4, T5, T6, T7, T8>, T1>, ISelect<T1, T2, T3, T4, T5, T6, T7, T8>
|
||||
where T1 : class
|
||||
where T2 : class
|
||||
where T3 : class
|
||||
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract class Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> : Select0Provider<ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>, T1>, ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>
|
||||
public abstract class Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> : Select0Provider<ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>, T1>, ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>
|
||||
where T1 : class
|
||||
where T2 : class
|
||||
where T3 : class
|
||||
|
@ -8,7 +8,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
class SelectGroupingProvider<TKey, TValue> : ISelectGrouping<TKey, TValue> {
|
||||
public class SelectGroupingProvider<TKey, TValue> : ISelectGrouping<TKey, TValue> {
|
||||
|
||||
internal object _select;
|
||||
internal ReadAnonymousTypeInfo _map;
|
||||
|
@ -11,7 +11,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
abstract partial class UpdateProvider<T1> : IUpdate<T1> where T1 : class {
|
||||
public abstract partial class UpdateProvider<T1> : IUpdate<T1> where T1 : class {
|
||||
protected IFreeSql _orm;
|
||||
protected CommonUtils _commonUtils;
|
||||
protected CommonExpression _commonExpression;
|
||||
@ -106,7 +106,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
internal int SplitExecuteAffrows(int valuesLimit, int parameterLimit) {
|
||||
protected int SplitExecuteAffrows(int valuesLimit, int parameterLimit) {
|
||||
var ss = SplitSource(valuesLimit, parameterLimit);
|
||||
var ret = 0;
|
||||
if (ss.Length <= 1) {
|
||||
@ -138,7 +138,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
ClearData();
|
||||
return ret;
|
||||
}
|
||||
async internal Task<int> SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) {
|
||||
async protected Task<int> SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit) {
|
||||
var ss = SplitSource(valuesLimit, parameterLimit);
|
||||
var ret = 0;
|
||||
if (ss.Length <= 1) {
|
||||
@ -170,7 +170,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
ClearData();
|
||||
return ret;
|
||||
}
|
||||
internal List<T1> SplitExecuteUpdated(int valuesLimit, int parameterLimit) {
|
||||
protected List<T1> SplitExecuteUpdated(int valuesLimit, int parameterLimit) {
|
||||
var ss = SplitSource(valuesLimit, parameterLimit);
|
||||
var ret = new List<T1>();
|
||||
if (ss.Length <= 1) {
|
||||
@ -202,7 +202,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
ClearData();
|
||||
return ret;
|
||||
}
|
||||
async internal Task<List<T1>> SplitExecuteUpdatedAsync(int valuesLimit, int parameterLimit) {
|
||||
async protected Task<List<T1>> SplitExecuteUpdatedAsync(int valuesLimit, int parameterLimit) {
|
||||
var ss = SplitSource(valuesLimit, parameterLimit);
|
||||
var ret = new List<T1>();
|
||||
if (ss.Length <= 1) {
|
||||
@ -236,7 +236,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
}
|
||||
#endregion
|
||||
|
||||
internal int RawExecuteAffrows() {
|
||||
protected int RawExecuteAffrows() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return 0;
|
||||
var dbParms = _params.Concat(_paramsSource).ToArray();
|
||||
@ -257,7 +257,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
this.ClearData();
|
||||
return affrows;
|
||||
}
|
||||
async internal Task<int> RawExecuteAffrowsAsync() {
|
||||
async protected Task<int> RawExecuteAffrowsAsync() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return 0;
|
||||
var dbParms = _params.Concat(_paramsSource).ToArray();
|
||||
@ -278,8 +278,8 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
this.ClearData();
|
||||
return affrows;
|
||||
}
|
||||
internal abstract List<T1> RawExecuteUpdated();
|
||||
internal abstract Task<List<T1>> RawExecuteUpdatedAsync();
|
||||
protected abstract List<T1> RawExecuteUpdated();
|
||||
protected abstract Task<List<T1>> RawExecuteUpdatedAsync();
|
||||
|
||||
public abstract int ExecuteAffrows();
|
||||
public abstract Task<int> ExecuteAffrowsAsync();
|
||||
|
@ -2,43 +2,46 @@
|
||||
using FreeSql.DatabaseModel;
|
||||
using FreeSql.Extensions.EntityUtil;
|
||||
using FreeSql.Internal.Model;
|
||||
using SafeObjectPool;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Internal {
|
||||
internal abstract class CommonUtils {
|
||||
public abstract class CommonUtils {
|
||||
|
||||
internal abstract string GetNoneParamaterSqlValue(List<DbParameter> specialParams, Type type, object value);
|
||||
internal abstract DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value);
|
||||
internal abstract DbParameter[] GetDbParamtersByObject(string sql, object obj);
|
||||
internal abstract string FormatSql(string sql, params object[] args);
|
||||
internal abstract string QuoteSqlName(string name);
|
||||
internal abstract string TrimQuoteSqlName(string name);
|
||||
internal abstract string QuoteParamterName(string name);
|
||||
internal abstract string IsNull(string sql, object value);
|
||||
internal abstract string StringConcat(string[] objs, Type[] types);
|
||||
internal abstract string Mod(string left, string right, Type leftType, Type rightType);
|
||||
internal abstract string QuoteWriteParamter(Type type, string paramterName);
|
||||
internal abstract string QuoteReadColumn(Type type, string columnName);
|
||||
public abstract string GetNoneParamaterSqlValue(List<DbParameter> specialParams, Type type, object value);
|
||||
public abstract DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value);
|
||||
public abstract DbParameter[] GetDbParamtersByObject(string sql, object obj);
|
||||
public abstract string FormatSql(string sql, params object[] args);
|
||||
public abstract string QuoteSqlName(string name);
|
||||
public abstract string TrimQuoteSqlName(string name);
|
||||
public abstract string QuoteParamterName(string name);
|
||||
public abstract string IsNull(string sql, object value);
|
||||
public abstract string StringConcat(string[] objs, Type[] types);
|
||||
public abstract string Mod(string left, string right, Type leftType, Type rightType);
|
||||
public abstract string QuoteWriteParamter(Type type, string paramterName);
|
||||
public abstract string QuoteReadColumn(Type type, string columnName);
|
||||
|
||||
internal IFreeSql _orm { get; set; }
|
||||
internal ICodeFirst CodeFirst => _orm.CodeFirst;
|
||||
internal TableInfo GetTableByEntity(Type entity) => Utils.GetTableByEntity(entity, this);
|
||||
internal List<DbTableInfo> dbTables { get; set; }
|
||||
internal object dbTablesLock = new object();
|
||||
public IFreeSql _orm { get; set; }
|
||||
public ICodeFirst CodeFirst => _orm.CodeFirst;
|
||||
public TableInfo GetTableByEntity(Type entity) => Utils.GetTableByEntity(entity, this);
|
||||
public List<DbTableInfo> dbTables { get; set; }
|
||||
public object dbTablesLock = new object();
|
||||
|
||||
public CommonUtils(IFreeSql orm) {
|
||||
_orm = orm;
|
||||
}
|
||||
|
||||
ConcurrentDictionary<Type, TableAttribute> dicConfigEntity = new ConcurrentDictionary<Type, TableAttribute>();
|
||||
internal ICodeFirst ConfigEntity<T>(Action<TableFluent<T>> entity) {
|
||||
public ICodeFirst ConfigEntity<T>(Action<TableFluent<T>> entity) {
|
||||
if (entity == null) return _orm.CodeFirst;
|
||||
var type = typeof(T);
|
||||
var table = dicConfigEntity.GetOrAdd(type, new TableAttribute());
|
||||
@ -47,7 +50,7 @@ namespace FreeSql.Internal {
|
||||
Utils.RemoveTableByEntity(type, this); //remove cache
|
||||
return _orm.CodeFirst;
|
||||
}
|
||||
internal ICodeFirst ConfigEntity(Type type, Action<TableFluent> entity) {
|
||||
public ICodeFirst ConfigEntity(Type type, Action<TableFluent> entity) {
|
||||
if (entity == null) return _orm.CodeFirst;
|
||||
var table = dicConfigEntity.GetOrAdd(type, new TableAttribute());
|
||||
var fluent = new TableFluent(type, table);
|
||||
@ -55,10 +58,10 @@ namespace FreeSql.Internal {
|
||||
Utils.RemoveTableByEntity(type, this); //remove cache
|
||||
return _orm.CodeFirst;
|
||||
}
|
||||
internal TableAttribute GetConfigEntity(Type type) {
|
||||
public TableAttribute GetConfigEntity(Type type) {
|
||||
return dicConfigEntity.TryGetValue(type, out var trytb) ? trytb : null;
|
||||
}
|
||||
internal TableAttribute GetEntityTableAttribute(Type type) {
|
||||
public TableAttribute GetEntityTableAttribute(Type type) {
|
||||
TableAttribute attr = null;
|
||||
if (_orm.Aop.ConfigEntity != null) {
|
||||
var aope = new Aop.ConfigEntityEventArgs(type);
|
||||
@ -84,7 +87,7 @@ namespace FreeSql.Internal {
|
||||
if (!string.IsNullOrEmpty(attr.SelectFilter)) return attr;
|
||||
return null;
|
||||
}
|
||||
internal ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto) {
|
||||
public ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto) {
|
||||
ColumnAttribute attr = null;
|
||||
if (_orm.Aop.ConfigEntityProperty != null) {
|
||||
var aope = new Aop.ConfigEntityPropertyEventArgs(type, proto);
|
||||
@ -137,7 +140,7 @@ namespace FreeSql.Internal {
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal string WhereObject(TableInfo table, string aliasAndDot, object dywhere) {
|
||||
public string WhereObject(TableInfo table, string aliasAndDot, object dywhere) {
|
||||
if (dywhere == null) return "";
|
||||
var type = dywhere.GetType();
|
||||
var primarys = table.Primarys;
|
||||
@ -182,7 +185,7 @@ namespace FreeSql.Internal {
|
||||
}
|
||||
}
|
||||
|
||||
internal string WhereItems<TEntity>(TableInfo table, string aliasAndDot, IEnumerable<TEntity> items) {
|
||||
public string WhereItems<TEntity>(TableInfo table, string aliasAndDot, IEnumerable<TEntity> items) {
|
||||
if (items == null || items.Any() == false) return null;
|
||||
if (table.Primarys.Any() == false) return null;
|
||||
var its = items.Where(a => a != null).ToArray();
|
||||
@ -231,5 +234,39 @@ namespace FreeSql.Internal {
|
||||
}
|
||||
return iidx == 1 ? sb.Remove(0, 5).Remove(sb.Length - 1, 1).ToString() : sb.Remove(0, 4).ToString();
|
||||
}
|
||||
|
||||
public static void PrevReheatConnectionPool(ObjectPool<DbConnection> pool, int minPoolSize) {
|
||||
if (minPoolSize <= 0) minPoolSize = Math.Min(5, pool.Policy.PoolSize);
|
||||
if (minPoolSize > pool.Policy.PoolSize) minPoolSize = pool.Policy.PoolSize;
|
||||
var initTestOk = true;
|
||||
var initStartTime = DateTime.Now;
|
||||
var initConns = new ConcurrentBag<Object<DbConnection>>();
|
||||
|
||||
try {
|
||||
var conn = pool.Get();
|
||||
initConns.Add(conn);
|
||||
pool.Policy.OnCheckAvailable(conn);
|
||||
} catch {
|
||||
initTestOk = false; //预热一次失败,后面将不进行
|
||||
}
|
||||
for (var a = 1; initTestOk && a < minPoolSize; a += 10) {
|
||||
if (initStartTime.Subtract(DateTime.Now).TotalSeconds > 3) break; //预热耗时超过3秒,退出
|
||||
var b = Math.Min(minPoolSize - a, 10); //每10个预热
|
||||
var initTasks = new Task[b];
|
||||
for (var c = 0; c < b; c++) {
|
||||
initTasks[c] = Task.Run(() => {
|
||||
try {
|
||||
var conn = pool.Get();
|
||||
initConns.Add(conn);
|
||||
pool.Policy.OnCheckAvailable(conn);
|
||||
} catch {
|
||||
initTestOk = false; //有失败,下一组退出预热
|
||||
}
|
||||
});
|
||||
}
|
||||
Task.WaitAll(initTasks);
|
||||
}
|
||||
while (initConns.TryTake(out var conn)) pool.Return(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace FreeSql.Internal.Model {
|
||||
class ReadAnonymousTypeInfo {
|
||||
public class ReadAnonymousTypeInfo {
|
||||
public PropertyInfo Property { get; set; }
|
||||
public string CsName { get; set; }
|
||||
public Type CsType { get; set; }
|
||||
@ -15,5 +15,5 @@ namespace FreeSql.Internal.Model {
|
||||
public List<ReadAnonymousTypeInfo> Childs = new List<ReadAnonymousTypeInfo>();
|
||||
public TableInfo Table { get; set; }
|
||||
}
|
||||
enum ReadAnonymousTypeInfoConsturctorType { Arguments, Properties }
|
||||
public enum ReadAnonymousTypeInfoConsturctorType { Arguments, Properties }
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace FreeSql.Internal.Model {
|
||||
class SelectColumnInfo {
|
||||
public class SelectColumnInfo {
|
||||
public ColumnInfo Column { get; set; }
|
||||
public SelectTableInfo Table { get; set; }
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace FreeSql.Internal.Model {
|
||||
class SelectTableInfo {
|
||||
public class SelectTableInfo {
|
||||
public TableInfo Table { get; set; }
|
||||
|
||||
private string _alias;
|
||||
@ -18,5 +18,5 @@ namespace FreeSql.Internal.Model {
|
||||
public ParameterExpression Parameter { get; set; }
|
||||
public SelectTableInfoType Type { get; set; }
|
||||
}
|
||||
enum SelectTableInfoType { From, LeftJoin, InnerJoin, RightJoin, Parent }
|
||||
public enum SelectTableInfoType { From, LeftJoin, InnerJoin, RightJoin, Parent }
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
using FreeSql.DataAnnotations;
|
||||
using FreeSql.Internal.Model;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
@ -637,8 +636,9 @@ namespace FreeSql.Internal {
|
||||
if (overrieds > 0) {
|
||||
cscode.AppendLine("}");
|
||||
Assembly assembly = null;
|
||||
if (MethodLazyLoadingComplier.Value == null) throw new Exception("【延时加载】功能需要安装 FreeSql.Extensions.LazyLoading.dll,可前往 nuget 下载");
|
||||
try {
|
||||
assembly = Generator.TemplateEngin._compiler.Value.CompileCode(cscode.ToString());
|
||||
assembly = MethodLazyLoadingComplier.Value.Invoke(null, new object[] { cscode.ToString() }) as Assembly;
|
||||
} catch (Exception ex) {
|
||||
throw new Exception($"【延时加载】{trytbTypeName} 编译错误:{ex.Message}\r\n\r\n{cscode}");
|
||||
}
|
||||
@ -651,8 +651,12 @@ namespace FreeSql.Internal {
|
||||
|
||||
return tbc.TryGetValue(entity, out var trytb2) ? trytb2 : trytb;
|
||||
}
|
||||
static Lazy<MethodInfo> MethodLazyLoadingComplier = new Lazy<MethodInfo>(() => {
|
||||
var type = Type.GetType("FreeSql.Extensions.LazyLoading.LazyLoadingComplier,FreeSql.Extensions.LazyLoading");
|
||||
return type.GetMethod("CompileCode");
|
||||
});
|
||||
|
||||
internal static T[] GetDbParamtersByObject<T>(string sql, object obj, string paramPrefix, Func<string, Type, object, T> constructorParamter) {
|
||||
public static T[] GetDbParamtersByObject<T>(string sql, object obj, string paramPrefix, Func<string, Type, object, T> constructorParamter) {
|
||||
if (string.IsNullOrEmpty(sql) || obj == null) return new T[0];
|
||||
var ttype = typeof(T);
|
||||
var type = obj.GetType();
|
||||
@ -668,7 +672,7 @@ namespace FreeSql.Internal {
|
||||
return ret.ToArray();
|
||||
}
|
||||
|
||||
internal static Dictionary<Type, bool> dicExecuteArrayRowReadClassOrTuple = new Dictionary<Type, bool> {
|
||||
public static Dictionary<Type, bool> dicExecuteArrayRowReadClassOrTuple = new Dictionary<Type, bool> {
|
||||
[typeof(bool)] = true,
|
||||
[typeof(sbyte)] = true,
|
||||
[typeof(short)] = true,
|
||||
@ -837,12 +841,14 @@ namespace FreeSql.Internal {
|
||||
|
||||
if (type == typeof(object) && indexes != null) {
|
||||
Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo> dynamicFunc = (type2, indexes2, row2, dataindex2, commonUtils2) => {
|
||||
dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写
|
||||
var expandodic = (IDictionary<string, object>)expando;
|
||||
//dynamic expando = new DynamicDictionary(); //动态类型字段 可读可写
|
||||
var expandodic = new Dictionary<string, object>();// (IDictionary<string, object>)expando;
|
||||
var fc = row2.FieldCount;
|
||||
for (var a = 0; a < fc; a++)
|
||||
//expando[row2.GetName(a)] = row2.GetValue(a);
|
||||
expandodic.Add(row2.GetName(a), row2.GetValue(a));
|
||||
return new RowInfo(expando, fc);
|
||||
//expando = expandodic;
|
||||
return new RowInfo(expandodic, fc);
|
||||
};
|
||||
return dynamicFunc;// Expression.Lambda<Func<Type, int[], DbDataReader, int, RowInfo>>(null);
|
||||
}
|
||||
@ -1092,14 +1098,10 @@ namespace FreeSql.Internal {
|
||||
static ConcurrentDictionary<Type, ConcurrentDictionary<Type, Func<object, object>>> _dicGetDataReaderValue = new ConcurrentDictionary<Type, ConcurrentDictionary<Type, Func<object, object>>>();
|
||||
static MethodInfo MethodArrayGetValue = typeof(Array).GetMethod("GetValue", new[] { typeof(int) });
|
||||
static MethodInfo MethodArrayGetLength = typeof(Array).GetMethod("GetLength", new[] { typeof(int) });
|
||||
static MethodInfo MethodMygisGeometryParse = typeof(MygisGeometry).GetMethod("Parse", new[] { typeof(string) });
|
||||
static MethodInfo MethodGuidTryParse = typeof(Guid).GetMethod("TryParse", new[] { typeof(string), typeof(Guid).MakeByRefType() });
|
||||
static MethodInfo MethodEnumParse = typeof(Enum).GetMethod("Parse", new[] { typeof(Type), typeof(string), typeof(bool) });
|
||||
static MethodInfo MethodConvertChangeType = typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) });
|
||||
static MethodInfo MethodTimeSpanFromSeconds = typeof(TimeSpan).GetMethod("FromSeconds");
|
||||
static MethodInfo MethodJTokenParse = typeof(JToken).GetMethod("Parse", new[] { typeof(string) });
|
||||
static MethodInfo MethodJObjectParse = typeof(JObject).GetMethod("Parse", new[] { typeof(string) });
|
||||
static MethodInfo MethodJArrayParse = typeof(JArray).GetMethod("Parse", new[] { typeof(string) });
|
||||
static MethodInfo MethodSByteTryParse = typeof(sbyte).GetMethod("TryParse", new[] { typeof(string), typeof(sbyte).MakeByRefType() });
|
||||
static MethodInfo MethodShortTryParse = typeof(short).GetMethod("TryParse", new[] { typeof(string), typeof(short).MakeByRefType() });
|
||||
static MethodInfo MethodIntTryParse = typeof(int).GetMethod("TryParse", new[] { typeof(string), typeof(int).MakeByRefType() });
|
||||
@ -1116,6 +1118,8 @@ namespace FreeSql.Internal {
|
||||
static MethodInfo MethodDateTimeOffsetTryParse = typeof(DateTimeOffset).GetMethod("TryParse", new[] { typeof(string), typeof(DateTimeOffset).MakeByRefType() });
|
||||
static MethodInfo MethodToString = typeof(Utils).GetMethod("ToStringConcat", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(object) }, null);
|
||||
static MethodInfo MethodBigIntegerParse = typeof(Utils).GetMethod("ToBigInteger", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(string) }, null);
|
||||
|
||||
public static ConcurrentBag<Func<LabelTarget, Expression, string, Expression>> GetDataReaderValueBlockExpressionSwitchTypeFullName = new ConcurrentBag<Func<LabelTarget, Expression, string, Expression>>();
|
||||
public static Expression GetDataReaderValueBlockExpression(Type type, Expression value) {
|
||||
var returnTarget = Expression.Label(typeof(object));
|
||||
var valueExp = Expression.Variable(typeof(object), "locvalue");
|
||||
@ -1177,16 +1181,6 @@ namespace FreeSql.Internal {
|
||||
}
|
||||
);
|
||||
break;
|
||||
case "MygisPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPoint)));
|
||||
case "MygisLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisLineString)));
|
||||
case "MygisPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPolygon)));
|
||||
case "MygisMultiPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPoint)));
|
||||
case "MygisMultiLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiLineString)));
|
||||
case "MygisMultiPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPolygon)));
|
||||
case "Newtonsoft.Json.Linq.JToken": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJTokenParse, Expression.Convert(valueExp, typeof(string))), typeof(JToken)));
|
||||
case "Newtonsoft.Json.Linq.JObject": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJObjectParse, Expression.Convert(valueExp, typeof(string))), typeof(JObject)));
|
||||
case "Newtonsoft.Json.Linq.JArray": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJArrayParse, Expression.Convert(valueExp, typeof(string))), typeof(JArray)));
|
||||
case "Npgsql.LegacyPostgis.PostgisGeometry": return Expression.Return(returnTarget, valueExp);
|
||||
case "System.Numerics.BigInteger": return Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodBigIntegerParse, Expression.Call(MethodToString, valueExp)), typeof(object)));
|
||||
case "System.TimeSpan":
|
||||
ParameterExpression tryparseVarTsExp, valueStrExp;
|
||||
@ -1373,6 +1367,12 @@ namespace FreeSql.Internal {
|
||||
typeof(object))
|
||||
);
|
||||
break;
|
||||
default:
|
||||
foreach (var switchFunc in GetDataReaderValueBlockExpressionSwitchTypeFullName) {
|
||||
var switchFuncRet = switchFunc(returnTarget, valueExp, type.FullName);
|
||||
if (switchFuncRet != null) return switchFuncRet;
|
||||
}
|
||||
break;
|
||||
}
|
||||
Expression switchExp = null;
|
||||
if (tryparseExp != null)
|
||||
@ -1437,45 +1437,7 @@ namespace FreeSql.Internal {
|
||||
});
|
||||
return func(value);
|
||||
}
|
||||
internal static object GetDataReaderValue22(Type type, object value) {
|
||||
if (value == null || value == DBNull.Value) return Activator.CreateInstance(type);
|
||||
if (type.FullName == "System.Byte[]") return value;
|
||||
if (type.IsArray) {
|
||||
var elementType = type.GetElementType();
|
||||
var valueArr = value as Array;
|
||||
if (elementType == valueArr.GetType().GetElementType()) return value;
|
||||
var len = valueArr.GetLength(0);
|
||||
var ret = Array.CreateInstance(elementType, len);
|
||||
for (var a = 0; a < len; a++) {
|
||||
var item = valueArr.GetValue(a);
|
||||
ret.SetValue(GetDataReaderValue22(elementType, item), a);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
if (type.IsNullableType()) type = type.GenericTypeArguments.First();
|
||||
if (type.IsEnum) return Enum.Parse(type, string.Concat(value), true);
|
||||
switch (type.FullName) {
|
||||
case "System.Guid":
|
||||
if (value.GetType() != type) return Guid.TryParse(string.Concat(value), out var tryguid) ? tryguid : Guid.Empty;
|
||||
return value;
|
||||
case "MygisPoint": return MygisPoint.Parse(string.Concat(value)) as MygisPoint;
|
||||
case "MygisLineString": return MygisLineString.Parse(string.Concat(value)) as MygisLineString;
|
||||
case "MygisPolygon": return MygisPolygon.Parse(string.Concat(value)) as MygisPolygon;
|
||||
case "MygisMultiPoint": return MygisMultiPoint.Parse(string.Concat(value)) as MygisMultiPoint;
|
||||
case "MygisMultiLineString": return MygisMultiLineString.Parse(string.Concat(value)) as MygisMultiLineString;
|
||||
case "MygisMultiPolygon": return MygisMultiPolygon.Parse(string.Concat(value)) as MygisMultiPolygon;
|
||||
case "Newtonsoft.Json.Linq.JToken": return JToken.Parse(string.Concat(value));
|
||||
case "Newtonsoft.Json.Linq.JObject": return JObject.Parse(string.Concat(value));
|
||||
case "Newtonsoft.Json.Linq.JArray": return JArray.Parse(string.Concat(value));
|
||||
case "Npgsql.LegacyPostgis.PostgisGeometry": return value;
|
||||
}
|
||||
if (type != value.GetType()) {
|
||||
if (type.FullName == "System.TimeSpan") return TimeSpan.FromSeconds(double.Parse(value.ToString()));
|
||||
return Convert.ChangeType(value, type);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
internal static string GetCsName(string name) {
|
||||
public static string GetCsName(string name) {
|
||||
name = Regex.Replace(name.TrimStart('@'), @"[^\w]", "_");
|
||||
return char.IsLetter(name, 0) ? name : string.Concat("_", name);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ namespace FreeSql.MySql.Curd {
|
||||
public override Task<List<T1>> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000);
|
||||
|
||||
|
||||
internal override long RawExecuteIdentity() {
|
||||
protected override long RawExecuteIdentity() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return 0;
|
||||
|
||||
@ -41,7 +41,7 @@ namespace FreeSql.MySql.Curd {
|
||||
this.ClearData();
|
||||
return ret;
|
||||
}
|
||||
async internal override Task<long> RawExecuteIdentityAsync() {
|
||||
async protected override Task<long> RawExecuteIdentityAsync() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return 0;
|
||||
|
||||
@ -62,7 +62,7 @@ namespace FreeSql.MySql.Curd {
|
||||
this.ClearData();
|
||||
return ret;
|
||||
}
|
||||
internal override List<T1> RawExecuteInserted() {
|
||||
protected override List<T1> RawExecuteInserted() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return new List<T1>();
|
||||
|
||||
@ -92,7 +92,7 @@ namespace FreeSql.MySql.Curd {
|
||||
this.ClearData();
|
||||
return ret;
|
||||
}
|
||||
async internal override Task<List<T1>> RawExecuteInsertedAsync() {
|
||||
async protected override Task<List<T1>> RawExecuteInsertedAsync() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return new List<T1>();
|
||||
|
@ -21,7 +21,7 @@ namespace FreeSql.MySql.Curd {
|
||||
public override Task<List<T1>> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000);
|
||||
|
||||
|
||||
internal override List<T1> RawExecuteUpdated() {
|
||||
protected override List<T1> RawExecuteUpdated() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return new List<T1>();
|
||||
|
||||
@ -53,7 +53,7 @@ namespace FreeSql.MySql.Curd {
|
||||
this.ClearData();
|
||||
return ret;
|
||||
}
|
||||
async internal override Task<List<T1>> RawExecuteUpdatedAsync() {
|
||||
async protected override Task<List<T1>> RawExecuteUpdatedAsync() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return new List<T1>();
|
||||
|
@ -0,0 +1,28 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<Version>0.6.1</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 MySql 5.6</Description>
|
||||
<PackageProjectUrl>https://github.com/2881099/FreeSql</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/2881099/FreeSql</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageTags>FreeSql;ORM</PackageTags>
|
||||
<PackageId>$(AssemblyName)</PackageId>
|
||||
<Title>$(AssemblyName)</Title>
|
||||
<IsPackable>true</IsPackable>
|
||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MySql.Data" Version="8.0.15" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\FreeSql\FreeSql.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -1,5 +1,4 @@
|
||||
using FreeSql.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MySql.Data.MySqlClient;
|
||||
using SafeObjectPool;
|
||||
using System;
|
||||
@ -11,8 +10,8 @@ using System.Threading;
|
||||
namespace FreeSql.MySql {
|
||||
class MySqlAdo : FreeSql.Internal.CommonProvider.AdoProvider {
|
||||
|
||||
public MySqlAdo() : base(null, null, DataType.MySql) { }
|
||||
public MySqlAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log, DataType.MySql) {
|
||||
public MySqlAdo() : base(DataType.MySql) { }
|
||||
public MySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.MySql) {
|
||||
base._util = util;
|
||||
if (!string.IsNullOrEmpty(masterConnectionString))
|
||||
MasterPool = new MySqlConnectionPool("主库", masterConnectionString, null, null);
|
@ -77,7 +77,7 @@ namespace FreeSql.MySql {
|
||||
_connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
|
||||
}
|
||||
|
||||
FreeUtil.PrevReheatConnectionPool(_pool, minPoolSize);
|
||||
FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ namespace FreeSql.MySql {
|
||||
|
||||
public MySqlExpression(CommonUtils common) : base(common) { }
|
||||
|
||||
internal override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
switch (exp.NodeType) {
|
||||
case ExpressionType.Convert:
|
||||
@ -132,7 +132,7 @@ namespace FreeSql.MySql {
|
||||
return null;
|
||||
}
|
||||
|
||||
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) {
|
||||
if (exp.Expression == null) {
|
||||
switch (exp.Member.Name) {
|
||||
case "Empty": return "''";
|
||||
@ -145,7 +145,7 @@ namespace FreeSql.MySql {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) {
|
||||
if (exp.Expression == null) {
|
||||
switch (exp.Member.Name) {
|
||||
case "Now": return "now()";
|
||||
@ -173,7 +173,7 @@ namespace FreeSql.MySql {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) {
|
||||
if (exp.Expression == null) {
|
||||
switch (exp.Member.Name) {
|
||||
case "Zero": return "0";
|
||||
@ -199,7 +199,7 @@ namespace FreeSql.MySql {
|
||||
return null;
|
||||
}
|
||||
|
||||
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
||||
@ -272,7 +272,7 @@ namespace FreeSql.MySql {
|
||||
}
|
||||
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
switch (exp.Method.Name) {
|
||||
case "Abs": return $"abs({getExp(exp.Arguments[0])})";
|
||||
@ -298,7 +298,7 @@ namespace FreeSql.MySql {
|
||||
}
|
||||
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
||||
@ -341,7 +341,7 @@ namespace FreeSql.MySql {
|
||||
}
|
||||
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
||||
@ -371,7 +371,7 @@ namespace FreeSql.MySql {
|
||||
}
|
||||
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
@ -1,16 +1,14 @@
|
||||
using FreeSql.Internal;
|
||||
using FreeSql.Internal.CommonProvider;
|
||||
using FreeSql.MySql.Curd;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace FreeSql.MySql {
|
||||
|
||||
class MySqlProvider<TMark> : IFreeSql<TMark> {
|
||||
public class MySqlProvider<TMark> : IFreeSql<TMark> {
|
||||
|
||||
static MySqlProvider() {
|
||||
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisPoint)] = true;
|
||||
@ -19,6 +17,19 @@ namespace FreeSql.MySql {
|
||||
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPoint)] = true;
|
||||
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiLineString)] = true;
|
||||
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPolygon)] = true;
|
||||
|
||||
var MethodMygisGeometryParse = typeof(MygisGeometry).GetMethod("Parse", new[] { typeof(string) });
|
||||
Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, string typeFullName) => {
|
||||
switch (typeFullName) {
|
||||
case "MygisPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPoint)));
|
||||
case "MygisLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisLineString)));
|
||||
case "MygisPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPolygon)));
|
||||
case "MygisMultiPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPoint)));
|
||||
case "MygisMultiLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiLineString)));
|
||||
case "MygisMultiPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPolygon)));
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public ISelect<T1> Select<T1>() where T1 : class => new MySqlSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, null);
|
||||
@ -34,17 +45,13 @@ namespace FreeSql.MySql {
|
||||
|
||||
public IAdo Ado { get; }
|
||||
public IAop Aop { get; }
|
||||
public ICache Cache { get; }
|
||||
public ICodeFirst CodeFirst { get; }
|
||||
public IDbFirst DbFirst { get; }
|
||||
public MySqlProvider(IDistributedCache cache, ILogger log, string masterConnectionString, string[] slaveConnectionString) {
|
||||
if (log == null) log = new LoggerFactory(new[] { new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() }).CreateLogger("FreeSql.MySql");
|
||||
|
||||
public MySqlProvider(string masterConnectionString, string[] slaveConnectionString) {
|
||||
this.InternalCommonUtils = new MySqlUtils(this);
|
||||
this.InternalCommonExpression = new MySqlExpression(this.InternalCommonUtils);
|
||||
|
||||
this.Cache = new CacheProvider(cache, log);
|
||||
this.Ado = new MySqlAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString);
|
||||
this.Ado = new MySqlAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString);
|
||||
this.Aop = new AopProvider();
|
||||
|
||||
this.DbFirst = new MySqlDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
|
||||
@ -65,7 +72,6 @@ namespace FreeSql.MySql {
|
||||
public void Dispose() {
|
||||
if (_isdisposed) return;
|
||||
(this.Ado as AdoProvider).Dispose();
|
||||
(this.Cache as CacheProvider)?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,8 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace FreeSql.MySql {
|
||||
@ -13,7 +15,7 @@ namespace FreeSql.MySql {
|
||||
public MySqlUtils(IFreeSql orm) : base(orm) {
|
||||
}
|
||||
|
||||
internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
|
||||
public override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
|
||||
if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
|
||||
var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value };
|
||||
var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
|
||||
@ -28,7 +30,7 @@ namespace FreeSql.MySql {
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal override DbParameter[] GetDbParamtersByObject(string sql, object obj) =>
|
||||
public override DbParameter[] GetDbParamtersByObject(string sql, object obj) =>
|
||||
Utils.GetDbParamtersByObject<MySqlParameter>(sql, obj, "?", (name, type, value) => {
|
||||
var ret = new MySqlParameter { ParameterName = $"?{name}", Value = value };
|
||||
var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
|
||||
@ -42,24 +44,24 @@ namespace FreeSql.MySql {
|
||||
return ret;
|
||||
});
|
||||
|
||||
internal override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args);
|
||||
internal override string QuoteSqlName(string name) {
|
||||
public override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args);
|
||||
public override string QuoteSqlName(string name) {
|
||||
var nametrim = name.Trim();
|
||||
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
|
||||
return nametrim; //原生SQL
|
||||
return $"`{nametrim.Trim('`').Replace(".", "`.`")}`";
|
||||
}
|
||||
internal override string TrimQuoteSqlName(string name) {
|
||||
public override string TrimQuoteSqlName(string name) {
|
||||
var nametrim = name.Trim();
|
||||
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
|
||||
return nametrim; //原生SQL
|
||||
return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}";
|
||||
}
|
||||
internal override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
|
||||
internal override string IsNull(string sql, object value) => $"ifnull({sql}, {value})";
|
||||
internal override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})";
|
||||
internal override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}";
|
||||
internal override string QuoteWriteParamter(Type type, string paramterName) {
|
||||
public override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
|
||||
public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})";
|
||||
public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})";
|
||||
public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}";
|
||||
public override string QuoteWriteParamter(Type type, string paramterName) {
|
||||
switch (type.FullName) {
|
||||
case "MygisPoint":
|
||||
case "MygisLineString":
|
||||
@ -71,7 +73,7 @@ namespace FreeSql.MySql {
|
||||
return paramterName;
|
||||
}
|
||||
|
||||
internal override string QuoteReadColumn(Type type, string columnName) {
|
||||
public override string QuoteReadColumn(Type type, string columnName) {
|
||||
switch (type.FullName) {
|
||||
case "MygisPoint":
|
||||
case "MygisLineString":
|
||||
@ -83,7 +85,7 @@ namespace FreeSql.MySql {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
internal override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, Type type, object value) {
|
||||
public override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, Type type, object value) {
|
||||
if (value == null) return "NULL";
|
||||
if (type == typeof(byte[])) {
|
||||
var bytes = value as byte[];
|
@ -80,7 +80,7 @@ namespace FreeSql.Oracle.Curd {
|
||||
}
|
||||
|
||||
ColumnInfo _identCol;
|
||||
internal override long RawExecuteIdentity() {
|
||||
protected override long RawExecuteIdentity() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return 0;
|
||||
|
||||
@ -123,7 +123,7 @@ namespace FreeSql.Oracle.Curd {
|
||||
this.ClearData();
|
||||
return ret;
|
||||
}
|
||||
async internal override Task<long> RawExecuteIdentityAsync() {
|
||||
async protected override Task<long> RawExecuteIdentityAsync() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return 0;
|
||||
|
||||
@ -167,14 +167,14 @@ namespace FreeSql.Oracle.Curd {
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal override List<T1> RawExecuteInserted() {
|
||||
protected override List<T1> RawExecuteInserted() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return new List<T1>();
|
||||
|
||||
this.RawExecuteAffrows();
|
||||
return _source;
|
||||
}
|
||||
async internal override Task<List<T1>> RawExecuteInsertedAsync() {
|
||||
async protected override Task<List<T1>> RawExecuteInsertedAsync() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return new List<T1>();
|
||||
|
@ -21,10 +21,10 @@ namespace FreeSql.Oracle.Curd {
|
||||
public override Task<List<T1>> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(200, 999);
|
||||
|
||||
|
||||
internal override List<T1> RawExecuteUpdated() {
|
||||
protected override List<T1> RawExecuteUpdated() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
internal override Task<List<T1>> RawExecuteUpdatedAsync() {
|
||||
protected override Task<List<T1>> RawExecuteUpdatedAsync() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<Version>0.6.1</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 Oracle 11</Description>
|
||||
<PackageProjectUrl>https://github.com/2881099/FreeSql</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/2881099/FreeSql</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageTags>FreeSql;ORM</PackageTags>
|
||||
<PackageId>$(AssemblyName)</PackageId>
|
||||
<Title>$(AssemblyName)</Title>
|
||||
<IsPackable>true</IsPackable>
|
||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="2.18.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\FreeSql\FreeSql.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -1,5 +1,4 @@
|
||||
using FreeSql.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Oracle.ManagedDataAccess.Client;
|
||||
using SafeObjectPool;
|
||||
using System;
|
||||
@ -10,8 +9,8 @@ using System.Threading;
|
||||
|
||||
namespace FreeSql.Oracle {
|
||||
class OracleAdo : FreeSql.Internal.CommonProvider.AdoProvider {
|
||||
public OracleAdo() : base(null, null, DataType.Oracle) { }
|
||||
public OracleAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log, DataType.Oracle) {
|
||||
public OracleAdo() : base(DataType.Oracle) { }
|
||||
public OracleAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.Oracle) {
|
||||
base._util = util;
|
||||
if (!string.IsNullOrEmpty(masterConnectionString))
|
||||
MasterPool = new OracleConnectionPool("主库", masterConnectionString, null, null);
|
@ -91,7 +91,7 @@ namespace FreeSql.Oracle {
|
||||
_connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
|
||||
}
|
||||
|
||||
FreeUtil.PrevReheatConnectionPool(_pool, minPoolSize);
|
||||
FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ namespace FreeSql.Oracle {
|
||||
|
||||
public OracleExpression(CommonUtils common) : base(common) { }
|
||||
|
||||
internal override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
switch (exp.NodeType) {
|
||||
case ExpressionType.Convert:
|
||||
@ -132,7 +132,7 @@ namespace FreeSql.Oracle {
|
||||
return null;
|
||||
}
|
||||
|
||||
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) {
|
||||
if (exp.Expression == null) {
|
||||
switch (exp.Member.Name) {
|
||||
case "Empty": return "''";
|
||||
@ -145,7 +145,7 @@ namespace FreeSql.Oracle {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) {
|
||||
if (exp.Expression == null) {
|
||||
switch (exp.Member.Name) {
|
||||
case "Now": return "systimestamp";
|
||||
@ -173,7 +173,7 @@ namespace FreeSql.Oracle {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) {
|
||||
if (exp.Expression == null) {
|
||||
switch (exp.Member.Name) {
|
||||
case "Zero": return "numtodsinterval(0,'second')";
|
||||
@ -199,7 +199,7 @@ namespace FreeSql.Oracle {
|
||||
return null;
|
||||
}
|
||||
|
||||
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
||||
@ -272,7 +272,7 @@ namespace FreeSql.Oracle {
|
||||
}
|
||||
throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
switch (exp.Method.Name) {
|
||||
case "Abs": return $"abs({getExp(exp.Arguments[0])})";
|
||||
@ -299,7 +299,7 @@ namespace FreeSql.Oracle {
|
||||
}
|
||||
throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
||||
@ -342,7 +342,7 @@ namespace FreeSql.Oracle {
|
||||
}
|
||||
throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
||||
@ -372,7 +372,7 @@ namespace FreeSql.Oracle {
|
||||
}
|
||||
throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
@ -1,16 +1,13 @@
|
||||
using FreeSql.Internal;
|
||||
using FreeSql.Internal.CommonProvider;
|
||||
using FreeSql.Oracle.Curd;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace FreeSql.Oracle {
|
||||
|
||||
class OracleProvider<TMark> : IFreeSql<TMark> {
|
||||
public class OracleProvider<TMark> : IFreeSql<TMark> {
|
||||
|
||||
public ISelect<T1> Select<T1>() where T1 : class => new OracleSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, null);
|
||||
public ISelect<T1> Select<T1>(object dywhere) where T1 : class => new OracleSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
|
||||
@ -25,17 +22,13 @@ namespace FreeSql.Oracle {
|
||||
|
||||
public IAdo Ado { get; }
|
||||
public IAop Aop { get; }
|
||||
public ICache Cache { get; }
|
||||
public ICodeFirst CodeFirst { get; }
|
||||
public IDbFirst DbFirst { get; }
|
||||
public OracleProvider(IDistributedCache cache, ILogger log, string masterConnectionString, string[] slaveConnectionString) {
|
||||
if (log == null) log = new LoggerFactory(new[] { new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() }).CreateLogger("FreeSql.Oracle");
|
||||
|
||||
public OracleProvider(string masterConnectionString, string[] slaveConnectionString) {
|
||||
this.InternalCommonUtils = new OracleUtils(this);
|
||||
this.InternalCommonExpression = new OracleExpression(this.InternalCommonUtils);
|
||||
|
||||
this.Cache = new CacheProvider(cache, log);
|
||||
this.Ado = new OracleAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString);
|
||||
this.Ado = new OracleAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString);
|
||||
this.Aop = new AopProvider();
|
||||
|
||||
this.DbFirst = new OracleDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
|
||||
@ -56,7 +49,6 @@ namespace FreeSql.Oracle {
|
||||
public void Dispose() {
|
||||
if (_isdisposed) return;
|
||||
(this.Ado as AdoProvider).Dispose();
|
||||
(this.Cache as CacheProvider)?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ using Oracle.ManagedDataAccess.Client;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
|
||||
namespace FreeSql.Oracle {
|
||||
@ -12,7 +13,7 @@ namespace FreeSql.Oracle {
|
||||
public OracleUtils(IFreeSql orm) : base(orm) {
|
||||
}
|
||||
|
||||
internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
|
||||
public override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
|
||||
if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
|
||||
var dbtype = (OracleDbType)_orm.CodeFirst.GetDbInfo(type)?.type;
|
||||
if (dbtype == OracleDbType.Boolean) {
|
||||
@ -25,7 +26,7 @@ namespace FreeSql.Oracle {
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal override DbParameter[] GetDbParamtersByObject(string sql, object obj) =>
|
||||
public override DbParameter[] GetDbParamtersByObject(string sql, object obj) =>
|
||||
Utils.GetDbParamtersByObject<OracleParameter>(sql, obj, ":", (name, type, value) => {
|
||||
var dbtype = (OracleDbType)_orm.CodeFirst.GetDbInfo(type)?.type;
|
||||
if (dbtype == OracleDbType.Boolean) {
|
||||
@ -37,28 +38,28 @@ namespace FreeSql.Oracle {
|
||||
return ret;
|
||||
});
|
||||
|
||||
internal override string FormatSql(string sql, params object[] args) => sql?.FormatOracleSQL(args);
|
||||
internal override string QuoteSqlName(string name) {
|
||||
public override string FormatSql(string sql, params object[] args) => sql?.FormatOracleSQL(args);
|
||||
public override string QuoteSqlName(string name) {
|
||||
var nametrim = name.Trim();
|
||||
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
|
||||
return nametrim; //原生SQL
|
||||
return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\"";
|
||||
}
|
||||
internal override string TrimQuoteSqlName(string name) {
|
||||
public override string TrimQuoteSqlName(string name) {
|
||||
var nametrim = name.Trim();
|
||||
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
|
||||
return nametrim; //原生SQL
|
||||
return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}";
|
||||
}
|
||||
internal override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
|
||||
internal override string IsNull(string sql, object value) => $"nvl({sql}, {value})";
|
||||
internal override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}";
|
||||
internal override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})";
|
||||
public override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
|
||||
public override string IsNull(string sql, object value) => $"nvl({sql}, {value})";
|
||||
public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}";
|
||||
public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})";
|
||||
|
||||
internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
|
||||
internal override string QuoteReadColumn(Type type, string columnName) => columnName;
|
||||
public override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
|
||||
public override string QuoteReadColumn(Type type, string columnName) => columnName;
|
||||
|
||||
internal override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, Type type, object value) {
|
||||
public override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, Type type, object value) {
|
||||
if (value == null) return "NULL";
|
||||
if (type == typeof(byte[])) {
|
||||
var bytes = value as byte[];
|
@ -21,7 +21,7 @@ namespace FreeSql.PostgreSQL.Curd {
|
||||
public override Task<List<T1>> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000);
|
||||
|
||||
|
||||
internal override long RawExecuteIdentity() {
|
||||
protected override long RawExecuteIdentity() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return 0;
|
||||
|
||||
@ -60,7 +60,7 @@ namespace FreeSql.PostgreSQL.Curd {
|
||||
this.ClearData();
|
||||
return ret;
|
||||
}
|
||||
async internal override Task<long> RawExecuteIdentityAsync() {
|
||||
async protected override Task<long> RawExecuteIdentityAsync() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return 0;
|
||||
|
||||
@ -100,7 +100,7 @@ namespace FreeSql.PostgreSQL.Curd {
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal override List<T1> RawExecuteInserted() {
|
||||
protected override List<T1> RawExecuteInserted() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return new List<T1>();
|
||||
|
||||
@ -130,7 +130,7 @@ namespace FreeSql.PostgreSQL.Curd {
|
||||
this.ClearData();
|
||||
return ret;
|
||||
}
|
||||
async internal override Task<List<T1>> RawExecuteInsertedAsync() {
|
||||
async protected override Task<List<T1>> RawExecuteInsertedAsync() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return new List<T1>();
|
||||
|
@ -21,7 +21,7 @@ namespace FreeSql.PostgreSQL.Curd {
|
||||
public override Task<List<T1>> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000);
|
||||
|
||||
|
||||
internal override List<T1> RawExecuteUpdated() {
|
||||
protected override List<T1> RawExecuteUpdated() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return new List<T1>();
|
||||
|
||||
@ -53,7 +53,7 @@ namespace FreeSql.PostgreSQL.Curd {
|
||||
this.ClearData();
|
||||
return ret;
|
||||
}
|
||||
async internal override Task<List<T1>> RawExecuteUpdatedAsync() {
|
||||
async protected override Task<List<T1>> RawExecuteUpdatedAsync() {
|
||||
var sql = this.ToSql();
|
||||
if (string.IsNullOrEmpty(sql)) return new List<T1>();
|
||||
|
@ -0,0 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<Version>0.6.1</Version>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Authors>YeXiangQin</Authors>
|
||||
<Description>FreeSql 数据库实现,基于 PostgreSQL 9.5</Description>
|
||||
<PackageProjectUrl>https://github.com/2881099/FreeSql</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/2881099/FreeSql</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageTags>FreeSql;ORM</PackageTags>
|
||||
<PackageId>$(AssemblyName)</PackageId>
|
||||
<Title>$(AssemblyName)</Title>
|
||||
<IsPackable>true</IsPackable>
|
||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||
<PackageReference Include="Npgsql.LegacyPostgis" Version="4.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\FreeSql\FreeSql.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -1,5 +1,4 @@
|
||||
using FreeSql.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Npgsql;
|
||||
using SafeObjectPool;
|
||||
@ -12,8 +11,8 @@ using System.Threading;
|
||||
|
||||
namespace FreeSql.PostgreSQL {
|
||||
class PostgreSQLAdo : FreeSql.Internal.CommonProvider.AdoProvider {
|
||||
public PostgreSQLAdo() : base(null, null, DataType.PostgreSQL) { }
|
||||
public PostgreSQLAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log, DataType.PostgreSQL) {
|
||||
public PostgreSQLAdo() : base(DataType.PostgreSQL) { }
|
||||
public PostgreSQLAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.PostgreSQL) {
|
||||
base._util = util;
|
||||
if (!string.IsNullOrEmpty(masterConnectionString))
|
||||
MasterPool = new PostgreSQLConnectionPool("主库", masterConnectionString, null, null);
|
@ -86,7 +86,7 @@ namespace FreeSql.PostgreSQL {
|
||||
_connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
|
||||
}
|
||||
|
||||
FreeUtil.PrevReheatConnectionPool(_pool, minPoolSize);
|
||||
FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize);
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ namespace FreeSql.PostgreSQL {
|
||||
|
||||
public PostgreSQLExpression(CommonUtils common) : base(common) { }
|
||||
|
||||
internal override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
switch (exp.NodeType) {
|
||||
case ExpressionType.Convert:
|
||||
@ -230,7 +230,7 @@ namespace FreeSql.PostgreSQL {
|
||||
return null;
|
||||
}
|
||||
|
||||
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) {
|
||||
if (exp.Expression == null) {
|
||||
switch (exp.Member.Name) {
|
||||
case "Empty": return "''";
|
||||
@ -243,7 +243,7 @@ namespace FreeSql.PostgreSQL {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) {
|
||||
if (exp.Expression == null) {
|
||||
switch (exp.Member.Name) {
|
||||
case "Now": return "current_timestamp";
|
||||
@ -271,7 +271,7 @@ namespace FreeSql.PostgreSQL {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) {
|
||||
if (exp.Expression == null) {
|
||||
switch (exp.Member.Name) {
|
||||
case "Zero": return "0";
|
||||
@ -297,7 +297,7 @@ namespace FreeSql.PostgreSQL {
|
||||
return null;
|
||||
}
|
||||
|
||||
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
||||
@ -372,7 +372,7 @@ namespace FreeSql.PostgreSQL {
|
||||
}
|
||||
throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
switch (exp.Method.Name) {
|
||||
case "Abs": return $"abs({getExp(exp.Arguments[0])})";
|
||||
@ -398,7 +398,7 @@ namespace FreeSql.PostgreSQL {
|
||||
}
|
||||
throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
||||
@ -441,7 +441,7 @@ namespace FreeSql.PostgreSQL {
|
||||
}
|
||||
throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
||||
@ -471,7 +471,7 @@ namespace FreeSql.PostgreSQL {
|
||||
}
|
||||
throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) {
|
||||
public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) {
|
||||
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
@ -1,9 +1,6 @@
|
||||
using FreeSql.Internal;
|
||||
using FreeSql.Internal.CommonProvider;
|
||||
using FreeSql.PostgreSQL.Curd;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Npgsql.LegacyPostgis;
|
||||
using NpgsqlTypes;
|
||||
@ -11,12 +8,13 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
namespace FreeSql.PostgreSQL {
|
||||
|
||||
class PostgreSQLProvider<TMark> : IFreeSql<TMark> {
|
||||
public class PostgreSQLProvider<TMark> : IFreeSql<TMark> {
|
||||
|
||||
static PostgreSQLProvider() {
|
||||
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(BitArray)] = true;
|
||||
@ -46,6 +44,19 @@ namespace FreeSql.PostgreSQL {
|
||||
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JToken)] = true;
|
||||
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JObject)] = true;
|
||||
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JArray)] = true;
|
||||
|
||||
var MethodJTokenParse = typeof(JToken).GetMethod("Parse", new[] { typeof(string) });
|
||||
var MethodJObjectParse = typeof(JObject).GetMethod("Parse", new[] { typeof(string) });
|
||||
var MethodJArrayParse = typeof(JArray).GetMethod("Parse", new[] { typeof(string) });
|
||||
Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, string typeFullName) => {
|
||||
switch (typeFullName) {
|
||||
case "Newtonsoft.Json.Linq.JToken": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJTokenParse, Expression.Convert(valueExp, typeof(string))), typeof(JToken)));
|
||||
case "Newtonsoft.Json.Linq.JObject": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJObjectParse, Expression.Convert(valueExp, typeof(string))), typeof(JObject)));
|
||||
case "Newtonsoft.Json.Linq.JArray": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJArrayParse, Expression.Convert(valueExp, typeof(string))), typeof(JArray)));
|
||||
case "Npgsql.LegacyPostgis.PostgisGeometry": return Expression.Return(returnTarget, valueExp);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public ISelect<T1> Select<T1>() where T1 : class => new PostgreSQLSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, null);
|
||||
@ -61,17 +72,13 @@ namespace FreeSql.PostgreSQL {
|
||||
|
||||
public IAdo Ado { get; }
|
||||
public IAop Aop { get; }
|
||||
public ICache Cache { get; }
|
||||
public ICodeFirst CodeFirst { get; }
|
||||
public IDbFirst DbFirst { get; }
|
||||
public PostgreSQLProvider(IDistributedCache cache, ILogger log, string masterConnectionString, string[] slaveConnectionString) {
|
||||
if (log == null) log = new LoggerFactory(new[] { new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() }).CreateLogger("FreeSql.PostgreSQL");
|
||||
|
||||
public PostgreSQLProvider(string masterConnectionString, string[] slaveConnectionString) {
|
||||
this.InternalCommonUtils = new PostgreSQLUtils(this);
|
||||
this.InternalCommonExpression = new PostgreSQLExpression(this.InternalCommonUtils);
|
||||
|
||||
this.Cache = new CacheProvider(cache, log);
|
||||
this.Ado = new PostgreSQLAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString);
|
||||
this.Ado = new PostgreSQLAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString);
|
||||
this.Aop = new AopProvider();
|
||||
|
||||
this.DbFirst = new PostgreSQLDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
|
||||
@ -92,7 +99,6 @@ namespace FreeSql.PostgreSQL {
|
||||
public void Dispose() {
|
||||
if (_isdisposed) return;
|
||||
(this.Ado as AdoProvider).Dispose();
|
||||
(this.Cache as CacheProvider)?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user