This commit is contained in:
jinghognbo 2022-11-28 16:07:50 +08:00
commit 3c991178c6
66 changed files with 622 additions and 228 deletions

View File

@ -11,7 +11,7 @@
<!--
经常出于版本交叉问题,暂时关闭,在每个项目上设置版本号
<PropertyGroup>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
-->

View File

@ -4,6 +4,7 @@ using FreeSql.Extensions;
using FreeSql.Internal;
using FreeSql.Internal.CommonProvider;
using FreeSql.Internal.Model;
using FreeSql.Odbc.Default;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
@ -351,6 +352,15 @@ namespace base_entity
public int aa { get; set; }
}
[Table(Name = "db2.sql_AAA_attr")]
[Index("{tablename}_xxx1", nameof(aa))]
[Index("{tablename}_xxx2", nameof(aa))]
public class SqliteAAA
{
[Column(Name = "aa_attr")]
public int aa { get; set; }
}
public class JoinConditionAttribute : Attribute
{
public string Condition { get; set; }
@ -372,8 +382,55 @@ namespace base_entity
}
public enum JoinTest01Enum { f1, f2, f3 }
public class AccessOdbcAdapter : OdbcAdapter
{
public override string UnicodeStringRawSql(object value, ColumnInfo mapColumn) => value == null ? "NULL" : string.Concat("'", value.ToString().Replace("'", "''"), "'");
}
private static IFreeSql CreateInstance(string connectString, DataType type)
{
IFreeSql client = new FreeSqlBuilder()
.UseConnectionString(type, connectString)
.Build();
if (DataType.Odbc.Equals(type))
{
client.SetOdbcAdapter(new AccessOdbcAdapter());
}
return client;
}
static void Main(string[] args)
{
var pams = new Dictionary<string, string>();
var sql2rscs = Utils.ReplaceSqlConstString("'', 'SARTEN ACERO VITR.18CM''''GRAFIT''''', 'a",
pams, "@lantin1");
//using (IFreeSql client = CreateInstance(@"Driver={Microsoft Access Driver (*.mdb)};DBQ=d:/accdb/2007.accdb", DataType.Odbc))
//{
// client.Aop.AuditValue += (_, e) =>
// {
// if (e.Object is Dictionary<string, object> dict)
// {
// foreach(var key in dict.Keys)
// {
// var val = dict[key];
// if (val == DBNull.Value) dict[key] = null;
// }
// e.ObjectAuditBreak = true;
// }
// };
// Dictionary<string, object> data = new Dictionary<string, object>();
// data.Add("ExpNo", "RSP0950008");
// data.Add("SPoint", "RSP0950004");
// data.Add("EPoint", "RSP095000440");
// data.Add("PType", "RS");
// data.Add("GType", "窨井轮廓线");
// data.Add("LineStyle", 2);
// data.Add("Memo", DBNull.Value);
// data.Add("ClassID", DBNull.Value);
// var kdkdksqlxx = client.InsertDict(data).AsTable("FZLINE").ToSql();
//}
BaseModel<User1>.fsql = 1;
BaseModel<UserGroup>.fsql = 2;
Console.WriteLine(BaseModel<User1>.fsql);
@ -389,6 +446,7 @@ namespace base_entity
.UseConnectionString(FreeSql.DataType.Sqlite, "data source=:memory:")
//.UseConnectionString(DataType.Sqlite, "data source=db1.db;attachs=db2.db")
//.UseSlave("data source=test1.db", "data source=test2.db", "data source=test3.db", "data source=test4.db")
//.UseSlaveWeight(10, 1, 1, 5)
@ -429,6 +487,62 @@ namespace base_entity
BaseEntity.Initialization(fsql, () => _asyncUow.Value);
#endregion
var dkdksql = fsql.Select<User1>().WithLock().From<UserGroup>()
.InnerJoin<UserGroup>((user, usergroup) => user.GroupId == usergroup.Id && usergroup.GroupName == "xxx")
.ToSql();
//Func<string> getName1 = () => "xxx";
//fsql.GlobalFilter.Apply<User1>("fil1", a => a.Nickname == getName1());
//var gnsql2 = fsql.Select<User1>().ToSql();
using (var ctx9 = fsql.CreateDbContext())
{
//var uset = ctx9.Set<UserGroup>();
//var item = new UserGroup
//{
// GroupName = "group1"
//};
//uset.Add(item);
//item.GroupName = "group1_2";
//uset.Update(item);
var uset = ctx9.Set<User1>();
var item = new User1
{
Nickname = "nick1",
Username = "user1"
};
uset.Add(item);
item.Nickname = "nick1_2";
item.Username = "user1_2";
uset.Update(item);
ctx9.SaveChanges();
}
var strs = new string[] { "a", "b", "c" };
var strssql1 = fsql.Select<User1>().Where(a => strs.Any(b => b == a.Nickname)).ToSql();
var strssql2 = fsql.Select<User1>().Where(a => strs.Any(b => a.Nickname.Contains(b))).ToSql();
var objs = new UserGroup[] { new UserGroup { GroupName = "a", Id = 1 }, new UserGroup { GroupName = "b", Id = 2 }, new UserGroup { GroupName = "c", Id = 3 } };
var objssql1 = fsql.Select<User1>().Where(a => objs.Any(b => b.GroupName == a.Nickname && b.Id == a.GroupId)).ToSql();
var tttsqlext01 = fsql.Select<User1>().ToSql(a => new
{
cou = SqlExt.Count(1).Over().PartitionBy(a.Id).ToValue(),
avg = SqlExt.Avg(1).Over().PartitionBy(a.Id).ToValue()
});
//fsql.CodeFirst.SyncStructure<SqliteAAA>();
fsql.CodeFirst.Entity<JoinTest01>(a => a.Property(p => p.code).IsRequired());
var repo1010 = fsql.GetRepository<JoinTest01>();
var jtitem = new JoinTest01 { id = 100 };
repo1010.Attach(jtitem);
jtitem.name = "name01";
repo1010.Update(jtitem);
var sqlt0a1 = fsql.InsertOrUpdate<>()
.SetSource(new

View File

@ -168,12 +168,9 @@ namespace FreeSql
return entity;
}
if (table.Primarys.Where(a => a.Attribute.IsIdentity).Count() == table.Primarys.Length)
{
Orm.ClearEntityPrimaryValueWithIdentity(EntityType, entity);
return await InsertAsync(entity, cancellationToken);
}
throw new Exception(DbContextStrings.CannotAdd_PrimaryKey_NotSet(Orm.GetEntityString(EntityType, entity)));
}
public virtual Task<int> UpdateAsync(TEntity entity, CancellationToken cancellationToken = default) => UpdateAsync(new[] { entity }, cancellationToken);
async public virtual Task<int> UpdateAsync(IEnumerable<TEntity> entitys, CancellationToken cancellationToken = default)
@ -271,7 +268,8 @@ namespace FreeSql
UpdateColumns = b.Item4,
UpdateColumnsString = string.Join(",", b.Item4.OrderBy(c => c))
}).ToArray());
var updateLogDict2 = updateLogDict.ToDictionary(a => a.Key, a => a.Value.ToDictionary(b => b.UpdateColumnsString, b => a.Value.Where(c => c.UpdateColumnsString == b.UpdateColumnsString).ToArray()));
var updateLogDict2 = updateLogDict.ToDictionary(a => a.Key, a =>
a.Value.GroupBy(b => b.UpdateColumnsString).ToDictionary(b => b.Key, b => a.Value.Where(c => c.UpdateColumnsString == b.Key).ToArray()));
foreach (var dl in updateLogDict2)
{
foreach (var dl2 in dl.Value)

View File

@ -221,12 +221,9 @@ namespace FreeSql
return entity;
}
if (table.Primarys.Where(a => a.Attribute.IsIdentity).Count() == table.Primarys.Length)
{
Orm.ClearEntityPrimaryValueWithIdentity(EntityType, entity);
return Insert(entity);
}
throw new Exception(DbContextStrings.CannotAdd_PrimaryKey_NotSet(Orm.GetEntityString(EntityType, entity)));
}
public virtual int Update(TEntity entity) => Update(new[] { entity });
public virtual int Update(IEnumerable<TEntity> entitys)
@ -322,7 +319,8 @@ namespace FreeSql
UpdateColumns = b.Item4,
UpdateColumnsString = string.Join(",", b.Item4.OrderBy(c => c))
}).ToArray());
var updateLogDict2 = updateLogDict.ToDictionary(a => a.Key, a => a.Value.ToDictionary(b => b.UpdateColumnsString, b => a.Value.Where(c => c.UpdateColumnsString == b.UpdateColumnsString).ToArray()));
var updateLogDict2 = updateLogDict.ToDictionary(a => a.Key, a =>
a.Value.GroupBy(b => b.UpdateColumnsString).ToDictionary(b => b.Key, b => a.Value.Where(c => c.UpdateColumnsString == b.Key).ToArray()));
foreach (var dl in updateLogDict2)
{
foreach (var dl2 in dl.Value)

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net60;net50;netcoreapp31;netcoreapp21;net45;net40</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net45;net40</TargetFrameworks>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>FreeSql;ncc;YeXiangQin</Authors>
<Description>FreeSql 扩展包,聚合根(实现室).</Description>
@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>1.0.3</Version>
<Version>1.0.6</Version>
</PropertyGroup>
<ItemGroup>
@ -26,7 +26,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\FreeSql.DbContext\FreeSql.DbContext.csproj" />
<PackageReference Include="FreeSql.DbContext" Version="3.2.666" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard2.0|AnyCPU'">

View File

@ -19,7 +19,7 @@
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<LangVersion>latest</LangVersion>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -15,7 +15,7 @@
<Title>$(AssemblyName)</Title>
<IsPackable>true</IsPackable>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net60</TargetFrameworks>
<TargetFrameworks>net60</TargetFrameworks>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<IsPackable>true</IsPackable>
<PackAsTool>true</PackAsTool>
@ -13,7 +13,7 @@
<PackageProjectUrl>https://github.com/2881099/FreeSql</PackageProjectUrl>
<RepositoryUrl>https://github.com/2881099/FreeSql</RepositoryUrl>
<PackageTags>FreeSql DbFirst 实体生成器</PackageTags>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -17,7 +17,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -83,20 +83,29 @@ namespace FreeSql
#region Set
static ConcurrentDictionary<Type, NativeTuple<PropertyInfo[], bool>> _dicGetDbSetProps = new ConcurrentDictionary<Type, NativeTuple<PropertyInfo[], bool>>();
static object _lockOnModelCreating = new object();
internal void InitPropSets()
{
var thisType = this.GetType();
var dicval = _dicGetDbSetProps.GetOrAdd(thisType, tp =>
NativeTuple.Create(
tp.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)
var isOnModelCreating = false;
if (_dicGetDbSetProps.TryGetValue(thisType, out var dicval) == false)
{
lock (_lockOnModelCreating)
{
if (_dicGetDbSetProps.TryGetValue(thisType, out dicval) == false)
{
dicval = NativeTuple.Create(
thisType.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)
.Where(a => a.PropertyType.IsGenericType &&
a.PropertyType == typeof(DbSet<>).MakeGenericType(a.PropertyType.GetGenericArguments()[0])).ToArray(),
false));
if (dicval.Item2 == false)
{
if (_dicGetDbSetProps.TryUpdate(thisType, NativeTuple.Create(dicval.Item1, true), dicval))
OnModelCreating(OrmOriginal.CodeFirst);
false);
_dicGetDbSetProps.TryAdd(thisType, dicval);
isOnModelCreating = true;
}
}
}
if (isOnModelCreating)
OnModelCreating(OrmOriginal.CodeFirst);
foreach (var prop in dicval.Item1)
{

View File

@ -98,6 +98,8 @@ namespace FreeSql
}
};
try
{
while (_prevCommands.Any() || states.Any())
{
var info = _prevCommands.Any() ? _prevCommands.Dequeue() : null;
@ -149,8 +151,12 @@ namespace FreeSql
await funcUpdate(isLiveUpdate);
}
}
}
finally
{
isFlushCommanding = false;
}
}
}
}
#endif

View File

@ -113,6 +113,8 @@ namespace FreeSql
}
};
try
{
while (_prevCommands.Any() || states.Any())
{
var info = _prevCommands.Any() ? _prevCommands.Dequeue() : null;
@ -164,7 +166,11 @@ namespace FreeSql
funcUpdate(isLiveUpdate);
}
}
}
finally
{
isFlushCommanding = false;
}
}
}
}

View File

@ -29,7 +29,7 @@ namespace FreeSql
public abstract partial class DbSet<TEntity> : IDbSet where TEntity : class
{
internal DbContext _db { get; set; }
internal IUnitOfWork _uow { get; set; }
internal virtual IUnitOfWork _uow { get; set; }
protected virtual ISelect<TEntity> OrmSelect(object dywhere)
{
@ -163,7 +163,7 @@ namespace FreeSql
return this;
}
Dictionary<Type, DbSet<object>> _dicDbSetObjects = new Dictionary<Type, DbSet<object>>();
internal Dictionary<Type, DbSet<object>> _dicDbSetObjects = new Dictionary<Type, DbSet<object>>();
DbSet<object> GetDbSetObject(Type et)
{
if (_dicDbSetObjects.TryGetValue(et, out var tryds)) return tryds;

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net60;net50;netcoreapp31;netcoreapp21;net45;net40</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net70;net60;net50;netcoreapp31;netcoreapp21;net45;net40</TargetFrameworks>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>FreeSql;ncc;YeXiangQin</Authors>
<Description>FreeSql is the ORM in .NetCore, .NetFramework, And Xamarin. It supports Mysql, Postgresql, SqlServer, Oracle, Sqlite, Firebird, Odbc, 达梦, 人大金仓, 神舟通用, 南大通用, 翰高, And Access</Description>
@ -17,7 +17,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>
@ -33,7 +33,7 @@
<PropertyGroup Condition="'$(TargetFramework)' == 'net40'">
<DefineConstants>net40</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net60' or '$(TargetFramework)' == 'net50' or '$(TargetFramework)' == 'netcoreapp31' or '$(TargetFramework)' == 'netcoreapp21'">
<PropertyGroup Condition="'$(TargetFramework)' == 'net70' or '$(TargetFramework)' == 'net60' or '$(TargetFramework)' == 'net50' or '$(TargetFramework)' == 'netcoreapp31' or '$(TargetFramework)' == 'netcoreapp21'">
<DefineConstants>netcoreapp</DefineConstants>
</PropertyGroup>
@ -41,6 +41,9 @@
<ItemGroup Condition="'$(TargetFramework)' == 'net60'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net70'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net50'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.0" />
</ItemGroup>

View File

@ -16,6 +16,18 @@ namespace FreeSql
_repo = repo;
}
IUnitOfWork _uowPriv;
internal override IUnitOfWork _uow
{
get => _uowPriv;
set
{
_uowPriv = value;
foreach (var dbset in _dicDbSetObjects.Values) //配合 UnitOfWorkManager
dbset._uow = _uowPriv;
}
}
protected override ISelect<TEntity> OrmSelect(object dywhere)
{
var select = base.OrmSelect(dywhere).AsTable(_repo.AsTableSelectValueInternal);

View File

@ -181,10 +181,11 @@ namespace FreeSql
UnitOfWork.Dispose();
UnitOfWork = olduow;
}
return affrows + _db.SaveChanges();
_db.SaveChanges();
return affrows;
}
var affrows2 = _dbset.EndEdit(data);
return affrows2 + _db.SaveChanges();
_db.SaveChanges();
return _dbset.EndEdit(data);
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net60;net50;netcoreapp31;netcoreapp21;net45;net40</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net70;net60;net50;netcoreapp31;netcoreapp21;net45;net40</TargetFrameworks>
<Authors>FreeSql;ncc;YeXiangQin</Authors>
<Description>FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/南大通用/翰高/Access, and read/write separation、and split table.</Description>
<PackageProjectUrl>https://github.com/2881099/FreeSql/wiki/Repository</PackageProjectUrl>
@ -17,7 +17,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -16,7 +16,7 @@
<PackageReference Include="MySqlConnector" Version="2.1.13" />
<PackageReference Include="Npgsql" Version="6.0.6" />
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="3.21.70" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>

View File

@ -2028,6 +2028,11 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT TOP 10 b.[Title]
Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(NoLock)", sql);
orm.Select<ToUpd1Pk>().WithLock().Limit(1).ToList();
sql = orm.Select<ToUpd1Pk>().WithLock().WithIndex("idx_01").Limit(1).ToSql().Replace("\r\n", "");
Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(index=idx_01, NoLock)", sql);
sql = orm.Select<ToUpd1Pk>().WithIndex("idx_01").WithLock().Limit(1).ToSql().Replace("\r\n", "");
Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(NoLock, index=idx_01)", sql);
sql = orm.Select<ToUpd1Pk>().WithLock(SqlServerLock.NoLock).Limit(1).ToSql().Replace("\r\n", "");
Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(NoLock)", sql);
orm.Select<ToUpd1Pk>().WithLock(SqlServerLock.NoLock).Limit(1).ToList();
@ -2039,6 +2044,11 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT TOP 10 b.[Title]
sql = orm.Select<ToUpd1Pk>().WithLock(SqlServerLock.UpdLock | SqlServerLock.RowLock | SqlServerLock.NoWait).Limit(1).ToSql().Replace("\r\n", "");
Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(UpdLock, RowLock, NoWait)", sql);
orm.Select<ToUpd1Pk>().WithLock(SqlServerLock.UpdLock | SqlServerLock.RowLock | SqlServerLock.NoWait).Limit(1).ToList();
sql = orm.Select<ToUpd1Pk>().WithLock(SqlServerLock.UpdLock | SqlServerLock.RowLock | SqlServerLock.NoWait).WithIndex("idx_01").Limit(1).ToSql().Replace("\r\n", "");
Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(index=idx_01, UpdLock, RowLock, NoWait)", sql);
sql = orm.Select<ToUpd1Pk>().WithIndex("idx_01").WithLock(SqlServerLock.UpdLock | SqlServerLock.RowLock | SqlServerLock.NoWait).Limit(1).ToSql().Replace("\r\n", "");
Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(UpdLock, RowLock, NoWait, index=idx_01)", sql);
});
var sql2 = orm.Select<Topic>()
@ -2049,6 +2059,46 @@ WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT TOP 10 b.[Title]
FROM [tb_topic22] a With(NoLock)
INNER JOIN [TestTypeInfo] a__Type With(NoLock) ON a__Type.[Guid] = a.[Id]", sql2);
sql2 = orm.Select<Topic>()
.WithSql("select * from topic with (nolock)")
.InnerJoin(a => a.Type.Guid == a.Id)
.WithLock()
.ToSql();
Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime]
FROM ( select * from topic with (nolock) ) a
INNER JOIN [TestTypeInfo] a__Type With(NoLock) ON a__Type.[Guid] = a.[Id]", sql2);
sql2 = orm.Select<Topic>()
.InnerJoin(a => a.Type.Guid == a.Id)
.WithLock()
.ToSql();
Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime]
FROM [tb_topic22] a With(NoLock)
INNER JOIN [TestTypeInfo] a__Type With(NoLock) ON a__Type.[Guid] = a.[Id]", sql2);
sql2 = orm.Select<Topic>()
.InnerJoin(a => a.Type.Guid == a.Id)
.WithLock()
.WithIndex("idx_02")
.ToSql();
Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime]
FROM [tb_topic22] a With(index=idx_02, NoLock)
INNER JOIN [TestTypeInfo] a__Type With(NoLock) ON a__Type.[Guid] = a.[Id]", sql2);
sql2 = orm.Select<Topic>()
.InnerJoin(a => a.Type.Guid == a.Id)
.WithLock()
.WithIndex("idx_02", new Dictionary<Type, string>
{
[typeof(TestTypeInfo)] = "idx_03"
})
.ToSql();
Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime]
FROM [tb_topic22] a With(index=idx_02, NoLock)
INNER JOIN [TestTypeInfo] a__Type With(index=idx_03, NoLock) ON a__Type.[Guid] = a.[Id]", sql2);
sql2 = orm.Select<Topic>()
.InnerJoin(a => a.Type.Guid == a.Id)
.WithLock(SqlServerLock.NoLock, new Dictionary<Type, bool>

View File

@ -82,7 +82,7 @@ namespace FreeSql
/// count() over(order by ...)
/// </summary>
/// <returns></returns>
public static ISqlOver<long> Count() => Over<long>("count()");
public static ISqlOver<long> Count(object column) => Over<long>($"count({expContext.Value.ParsedContent["column"]})");
/// <summary>
/// sum(..) over(order by ...)
/// </summary>
@ -93,7 +93,7 @@ namespace FreeSql
/// avg(..) over(order by ...)
/// </summary>
/// <returns></returns>
public static ISqlOver<decimal> Avg() => Over<decimal>($"avg({expContext.Value.ParsedContent["column"]})");
public static ISqlOver<decimal> Avg(object column) => Over<decimal>($"avg({expContext.Value.ParsedContent["column"]})");
/// <summary>
/// max(..) over(order by ...)
/// </summary>

View File

@ -876,6 +876,7 @@ SELECT ");
/// <returns></returns>
public static InsertDictImpl InsertDict(this IFreeSql freesql, Dictionary<string, object> source)
{
LocalReplaceDictDBNullValue(source);
var insertDict = new InsertDictImpl(freesql);
insertDict._insertProvider.AppendData(source);
return insertDict;
@ -887,10 +888,21 @@ SELECT ");
/// <returns></returns>
public static InsertDictImpl InsertDict(this IFreeSql freesql, IEnumerable<Dictionary<string, object>> source)
{
if (source?.Any() == true) foreach (var dict in source) LocalReplaceDictDBNullValue(dict);
var insertDict = new InsertDictImpl(freesql);
insertDict._insertProvider.AppendData(source);
return insertDict;
}
static void LocalReplaceDictDBNullValue(Dictionary<string, object> dict)
{
if (dict == null) return;
var keys = dict.Keys;
foreach (var key in keys)
{
var val = dict[key];
if (val == DBNull.Value) dict[key] = null;
}
}
/// <summary>
/// 更新数据字典 Dictionary&lt;string, object&gt;
/// </summary>
@ -898,6 +910,7 @@ SELECT ");
/// <returns></returns>
public static UpdateDictImpl UpdateDict(this IFreeSql freesql, Dictionary<string, object> source)
{
LocalReplaceDictDBNullValue(source);
var updateDict = new UpdateDictImpl(freesql);
updateDict._updateProvider.SetSource(source);
return updateDict;
@ -909,6 +922,7 @@ SELECT ");
/// <returns></returns>
public static UpdateDictImpl UpdateDict(this IFreeSql freesql, IEnumerable<Dictionary<string, object>> source)
{
if (source?.Any() == true) foreach (var dict in source) LocalReplaceDictDBNullValue(dict);
var updateDict = new UpdateDictImpl(freesql);
updateDict._updateProvider.SetSource(source);
return updateDict;
@ -929,12 +943,14 @@ SELECT ");
/// <returns></returns>
public static InsertOrUpdateDictImpl InsertOrUpdateDict(this IFreeSql freesql, Dictionary<string, object> source)
{
LocalReplaceDictDBNullValue(source);
var insertOrUpdateDict = new InsertOrUpdateDictImpl(freesql);
insertOrUpdateDict._insertOrUpdateProvider.SetSource(source);
return insertOrUpdateDict;
}
public static InsertOrUpdateDictImpl InsertOrUpdateDict(this IFreeSql freesql, IEnumerable<Dictionary<string, object>> source)
{
if (source?.Any() == true) foreach (var dict in source) LocalReplaceDictDBNullValue(dict);
var insertOrUpdateDict = new InsertOrUpdateDictImpl(freesql);
insertOrUpdateDict._insertOrUpdateProvider.SetSource(source);
return insertOrUpdateDict;
@ -946,6 +962,7 @@ SELECT ");
/// <returns></returns>
public static DeleteDictImpl DeleteDict(this IFreeSql freesql, Dictionary<string, object> source)
{
LocalReplaceDictDBNullValue(source);
var deleteDict = new DeleteDictImpl(freesql);
UpdateProvider<Dictionary<string, object>>.GetDictionaryTableInfo(source, deleteDict._deleteProvider._orm, ref deleteDict._deleteProvider._table);
var primarys = UpdateDictImpl.GetPrimarys(deleteDict._deleteProvider._table, source.Keys.ToArray());
@ -959,6 +976,7 @@ SELECT ");
/// <returns></returns>
public static DeleteDictImpl DeleteDict(this IFreeSql freesql, IEnumerable<Dictionary<string, object>> source)
{
if (source?.Any() == true) foreach (var dict in source) LocalReplaceDictDBNullValue(dict);
DeleteDictImpl deleteDict = null;
if (source.Select(a => string.Join(",", a.Keys)).Distinct().Count() == 1)
{

View File

@ -17,7 +17,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -1201,7 +1201,7 @@
</summary>
<returns></returns>
</member>
<member name="M:FreeSql.SqlExt.Count">
<member name="M:FreeSql.SqlExt.Count(System.Object)">
<summary>
count() over(order by ...)
</summary>
@ -1214,7 +1214,7 @@
<param name="column"></param>
<returns></returns>
</member>
<member name="M:FreeSql.SqlExt.Avg">
<member name="M:FreeSql.SqlExt.Avg(System.Object)">
<summary>
avg(..) over(order by ...)
</summary>

View File

@ -1019,6 +1019,9 @@ namespace FreeSql.Internal
}
else if (exp3.Arguments[a].IsParameter())
exp3InvokeParams[a] = exp3.Arguments[a].Type.CreateInstanceGetDefaultValue();
else if (Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(exp3.Arguments[a].Type.NullableTypeOrThis()) == false)
exp3InvokeParams[a] = exp3.Arguments[a].Type.CreateInstanceGetDefaultValue();
else
{
var exp3CsValue = eccContent.StartsWith("N'") ?
@ -1045,8 +1048,8 @@ namespace FreeSql.Internal
typeof(ThreadLocal<ExpressionCallContext>).GetProperty("Value").SetValue(eccField.GetValue(null), ecc, null);
try
{
var sqlRet = exp3.Method.Invoke(null, exp3InvokeParams);
if (string.IsNullOrEmpty(ecc.Result) && sqlRet is string) ecc.Result = string.Concat(sqlRet);
var invokeReturn = exp3.Method.Invoke(null, exp3InvokeParams);
if (string.IsNullOrEmpty(ecc.Result) && invokeReturn is string) ecc.Result = string.Concat(invokeReturn);
if (string.IsNullOrEmpty(ecc.Result) && exp3MethodParams.Any()) ecc.Result = ecc.ParsedContent[exp3MethodParams[0].Name];
if (ecc.UserParameters?.Any() == true) tsc.dbParams?.AddRange(ecc.UserParameters);
return ecc.Result;
@ -1695,7 +1698,7 @@ namespace FreeSql.Internal
if (oper2.NodeType == ExpressionType.Parameter)
{
var oper2Parm = oper2 as ParameterExpression;
expStack.Push(exp2.Type.IsAbstract || exp2.Type.IsInterface ? oper2Parm : Expression.Parameter(exp2.Type, oper2Parm.Name));
expStack.Push(exp2.Type.IsAbstract || exp2.Type.IsInterface || exp2.Type.IsAssignableFrom(oper2Parm.Type) ? oper2Parm : Expression.Parameter(exp2.Type, oper2Parm.Name));
}
else
expStack.Push(oper2);
@ -2283,6 +2286,12 @@ namespace FreeSql.Internal
return Expression.Property(_replaceExp, node.Member.Name);
return base.VisitMember(node);
}
protected override Expression VisitParameter(ParameterExpression node)
{
if (node == oldParameter)
return _replaceExp;
return base.VisitParameter(node);
}
}
public class ReplaceHzyTupleToMultiParam : ExpressionVisitor
@ -2502,7 +2511,7 @@ namespace FreeSql.Internal
if (whereGlobalFilter.Any()) select._whereGlobalFilter.AddRange(whereGlobalFilter);
}
}
while (true)
while (exp3Stack.Any())
{
var exp4 = exp3Stack.Pop();
if (exp4.NodeType == ExpressionType.MemberAccess)
@ -2546,8 +2555,15 @@ namespace FreeSql.Internal
var callExp = exp4 as MethodCallExpression;
switch (callExp.Method.Name)
{
case "Exists":
case "Any":
if (callExp.Arguments.Count == 2)
if (callExp.Method.Name == "Exists" && callExp.Arguments.Count == 1 && callExp.Type.IsGenericType && callExp.Type.GetGenericTypeDefinition().IsAssignableFrom(typeof(IList<>)))
{
select._tables[0].Parameter = (callExp.Arguments[0] as LambdaExpression)?.Parameters.FirstOrDefault();
LocalSetSelectProviderAlias(select._tables[0].Parameter.Name);
select.InternalWhere(callExp.Arguments[0]);
}
if (callExp.Method.Name == "Any" && callExp.Arguments.Count == 2)
{
select._tables[0].Parameter = (callExp.Arguments[1] as LambdaExpression)?.Parameters.FirstOrDefault();
LocalSetSelectProviderAlias(select._tables[0].Parameter.Name);

View File

@ -615,18 +615,21 @@ namespace FreeSql.Internal.CommonProvider
{
if (exp == null) return this as TSelect;
_tables[0].Parameter = exp.Parameters[0];
if (_tables.Count > 1 && _tables[1].Table.Type == typeof(T2)) _tables[1].Parameter = exp.Parameters[1];
return this.InternalJoin(exp?.Body, SelectTableInfoType.LeftJoin);
}
public TSelect InnerJoin<T2>(Expression<Func<T1, T2, bool>> exp)
{
if (exp == null) return this as TSelect;
_tables[0].Parameter = exp.Parameters[0];
if (_tables.Count > 1 && _tables[1].Table.Type == typeof(T2)) _tables[1].Parameter = exp.Parameters[1];
return this.InternalJoin(exp?.Body, SelectTableInfoType.InnerJoin);
}
public TSelect RightJoin<T2>(Expression<Func<T1, T2, bool>> exp)
{
if (exp == null) return this as TSelect;
_tables[0].Parameter = exp.Parameters[0];
if (_tables.Count > 1 && _tables[1].Table.Type == typeof(T2)) _tables[1].Parameter = exp.Parameters[1];
return this.InternalJoin(exp?.Body, SelectTableInfoType.RightJoin);
}

View File

@ -483,7 +483,11 @@ namespace FreeSql.Internal.CommonProvider
var curPropName = parentNameSplits[k];
if (curTb.Table.Properties.TryGetValue(parentNameSplits[k], out var tryprop) == false)
{
k++;
if (++k >= parentNameSplits.Length)
{
iscontinue = true;
break;
}
curPropName = $"{curPropName}__{parentNameSplits[k]}";
if (curTb.Table.Properties.TryGetValue(parentNameSplits[k], out tryprop) == false)
{

View File

@ -1336,6 +1336,8 @@ namespace FreeSql.Internal.CommonProvider
}).ToArray();
var arrExp = Expression.NewArrayInit(tbref.RefColumns[0].CsType, listKeys.Where(a => a != null).SelectMany(a => a).Distinct()
.Select(a => Expression.Constant(Utils.GetDataReaderValue(tbref.RefColumns[0].CsType, a), tbref.RefColumns[0].CsType)).ToArray());
if (arrExp.Expressions.Any())
{
var otmExpParm1 = Expression.Parameter(typeof(TNavigate), "a");
var containsMethod = _dicTypeMethod.GetOrAdd(tbref.RefColumns[0].CsType, et => new ConcurrentDictionary<string, MethodInfo>()).GetOrAdd("Contains", mn =>
typeof(Enumerable).GetMethods().Where(a => a.Name == mn).First()).MakeGenericMethod(tbref.RefColumns[0].CsType);
@ -1356,6 +1358,7 @@ namespace FreeSql.Internal.CommonProvider
if (selectExp == null) subList = subSelect.ToList(true);
else subList = subSelect.ToList<TNavigate>(selectExp);
}
}
if (subList.Any() == false)
{
@ -1536,6 +1539,17 @@ namespace FreeSql.Internal.CommonProvider
var bindings = new List<MemberBinding>();
if (imni.IsOutputPrimary) bindings.AddRange(imni.Table.Primarys.Select(a => Expression.Bind(imni.Table.Properties[a.CsName], Expression.MakeMemberAccess(imni.CurrentExpression, imni.Table.Properties[a.CsName]))));
if (imni.Childs.Any()) bindings.AddRange(imni.Childs.Select(a => Expression.Bind(imni.Table.Properties[a.Key], GetIncludeManyNewInitExpression(a.Value))));
var pgarrayToManys = imni.Table.GetAllTableRef().Select(tr =>
{
if (tr.Value.RefType != TableRefType.PgArrayToMany) return null;
var reftb = _orm.CodeFirst.GetTableByEntity(tr.Value.RefEntityType);
if (tr.Value.RefColumns[0] == reftb.Primarys[0])
{
bindings.Add(Expression.Bind(imni.Table.Properties[tr.Value.Columns[0].CsName], Expression.MakeMemberAccess(imni.CurrentExpression, imni.Table.Properties[tr.Value.Columns[0].CsName])));
return tr.Key;
}
return null;
}).ToList();
return Expression.MemberInit(imni.Table.Type.InternalNewExpression(), bindings);
}

View File

@ -2458,6 +2458,7 @@ namespace FreeSql.Internal
}
if (sidx < sql.Length && sql[sidx] == '\'')
{
sidx++;
startLength += 2;
continue;
}

View File

@ -51,7 +51,7 @@ namespace FreeSql.ClickHouse
}
public override DbParameter[] GetDbParamtersByObject(string sql, object obj) =>
Utils.GetDbParamtersByObject<DbParameter>(sql, obj, "?", (name, type, value) =>
Utils.GetDbParamtersByObject<DbParameter>(sql, obj, "@", (name, type, value) =>
{
if (value is string str)
value = str?.Replace("\t", "\\t")
@ -59,7 +59,7 @@ namespace FreeSql.ClickHouse
.Replace("\n", "\\n")
.Replace("\r", "\\r")
.Replace("/", "\\/");
DbParameter ret = new ClickHouseDbParameter { ParameterName = $"?{name}", Value = value };
DbParameter ret = new ClickHouseDbParameter { ParameterName = $"@{name}", Value = value };
var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
if (tp != null)
ret.DbType = (DbType)tp.Value;

View File

@ -19,7 +19,7 @@
<SignAssembly>False</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -200,7 +200,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname);
if (istmpatler == false)
{
var existsPrimary = LocalExecuteScalar(tbname[0], _commonUtils.FormatSql(" select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname));
var existsPrimary = LocalExecuteScalar(tbname[0], _commonUtils.FormatSql(" select 1 from information_schema.columns where table_schema={0} and table_name={1} and column_key = 'PRI' limit 1", tbname));
foreach (var tbcol in tb.ColumnsByPosition)
{
var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1;

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.RegularExpressions;
namespace FreeSql.Custom.SqlServer
{
@ -44,7 +45,7 @@ namespace FreeSql.Custom.SqlServer
if (_limit > 0 || _skip > 0)
{
if (string.IsNullOrEmpty(_orderby))
if (string.IsNullOrEmpty(_orderby) && (_limit > 1 || _skip > 0)) //TOP 1 不自动 order by
{
if (string.IsNullOrEmpty(_groupby))
{
@ -63,13 +64,15 @@ namespace FreeSql.Custom.SqlServer
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
for (var a = 0; a < tbsfrom.Length; a++)
{
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias);
var alias = LocalGetTableAlias(tbsfrom[a].Table.Type, tbUnion[tbsfrom[a].Table.Type], tbsfrom[a].Alias, _aliasRule);
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(alias);
if (tbsjoin.Length > 0)
{
//如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1
for (var b = 1; b < tbsfrom.Length; b++)
{
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias);
alias = LocalGetTableAlias(tbsfrom[b].Table.Type, tbUnion[tbsfrom[b].Table.Type], tbsfrom[b].Alias, _aliasRule);
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(alias);
if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1");
else
@ -110,7 +113,8 @@ namespace FreeSql.Custom.SqlServer
sb.Append(" \r\nRIGHT JOIN ");
break;
}
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition);
var alias = LocalGetTableAlias(tb.Table.Type, tbUnion[tb.Table.Type], tb.Alias, _aliasRule);
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition);
if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade);
if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")");
}
@ -176,13 +180,15 @@ namespace FreeSql.Custom.SqlServer
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
for (var a = 0; a < tbsfrom.Length; a++)
{
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias);
var alias = LocalGetTableAlias(tbsfrom[a].Table.Type, tbUnion[tbsfrom[a].Table.Type], tbsfrom[a].Alias, _aliasRule);
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(alias);
if (tbsjoin.Length > 0)
{
//如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1
for (var b = 1; b < tbsfrom.Length; b++)
{
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias);
alias = LocalGetTableAlias(tbsfrom[b].Table.Type, tbUnion[tbsfrom[b].Table.Type], tbsfrom[b].Alias, _aliasRule);
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(alias);
if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1");
else
@ -223,7 +229,8 @@ namespace FreeSql.Custom.SqlServer
sb.Append(" \r\nRIGHT JOIN ");
break;
}
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition);
var alias = LocalGetTableAlias(tb.Table.Type, tbUnion[tb.Table.Type], tb.Alias, _aliasRule);
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition);
if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade);
if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")");
}
@ -271,6 +278,17 @@ namespace FreeSql.Custom.SqlServer
}
#endregion
static string LocalGetTableAlias(Type entityType, string tbname, string alias, Func<Type, string, string> aliasRule)
{
if (aliasRule != null)
{
alias = aliasRule(entityType, alias);
if (tbname.IndexOf(' ') != -1) //还可以这样select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList()
alias = Regex.Replace(alias, @" With\([^\)]+\)", ""); //替换 WithLock、WithIndex
}
return alias;
}
public CustomSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override ISelect<T1, T2> From<T2>(Expression<Func<ISelectFromExpression<T1>, T2, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect<T1, T2>(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3> From<T2, T3>(Expression<Func<ISelectFromExpression<T1>, T2, T3, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect<T1, T2, T3>(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }

View File

@ -15,7 +15,7 @@
<Title>$(AssemblyName)</Title>
<IsPackable>true</IsPackable>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -64,7 +64,7 @@ namespace FreeSql.Firebird
{
_connectionString = value ?? "";
var minPoolSize = 0;
var minPoolSize = 1;
var pattern = @"Min\s*pool\s*size\s*=\s*(\d+)";
var m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
if (m.Success)

View File

@ -33,7 +33,7 @@ namespace FreeSql.Firebird
{ typeof(double).FullName, CsToDb.New(FbDbType.Double, "double precision","double precision NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(FbDbType.Double, "double precision", "double precision", false, true, null) },
{ typeof(decimal).FullName, CsToDb.New(FbDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(FbDbType.Numeric, "decimal", "decimal(10,2)", false, true, null) },
{ typeof(string).FullName, CsToDb.New(FbDbType.VarChar, "varchar", "varchar(255)", false, null, "") },
{ typeof(string).FullName, CsToDb.New(FbDbType.VarChar, "varchar", "varchar(200)", false, null, "") },
{ typeof(TimeSpan).FullName, CsToDb.New(FbDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(FbDbType.Time, "time", "time",false, true, null) },
{ typeof(DateTime).FullName, CsToDb.New(FbDbType.TimeStamp, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(FbDbType.TimeStamp, "timestamp", "timestamp", false, true, null) },
@ -136,7 +136,7 @@ namespace FreeSql.Firebird
{
sb.Append("CREATE ");
if (uk.IsUnique) sb.Append("UNIQUE ");
sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(" ON ").Append(createTableName).Append("(");
sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname))).Append(" ON ").Append(createTableName).Append("(");
foreach (var tbcol in uk.Columns)
{
sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name));
@ -269,5 +269,18 @@ where d.rdb$index_type = 0 and trim(d.rdb$relation_name) = {0}", tboldname ?? tb
}
return sb.Length == 0 ? null : sb.ToString();
}
public override int ExecuteDDLStatements(string ddl)
{
if (string.IsNullOrEmpty(ddl)) return 0;
var scripts = ddl.Split(new string[] { ";\r\n" }, StringSplitOptions.None).Where(a => string.IsNullOrEmpty(a.Trim()) == false).ToArray();
if (scripts.Any() == false) return 0;
var affrows = 0;
foreach (var script in scripts)
affrows += base.ExecuteDDLStatements(script);
return affrows;
}
}
}

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -15,7 +15,7 @@
<Title>$(AssemblyName)</Title>
<IsPackable>true</IsPackable>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -63,7 +63,7 @@ namespace FreeSql.MsAccess
{
_connectionString = value ?? "";
var minPoolSize = 0;
var minPoolSize = 1;
var pattern = @"Min\s*pool\s*size\s*=\s*(\d+)";
var m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
if (m.Success)

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -212,7 +212,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname);
if (istmpatler == false)
{
var existsPrimary = LocalExecuteScalar(tbname[0], _commonUtils.FormatSql(" select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname));
var existsPrimary = LocalExecuteScalar(tbname[0], _commonUtils.FormatSql(" select 1 from information_schema.columns where table_schema={0} and table_name={1} and column_key = 'PRI' limit 1", tbname));
foreach (var tbcol in tb.ColumnsByPosition)
{
if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) ||

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -37,7 +37,8 @@ namespace FreeSql.Odbc.Default
return ret;
});
public override string FormatSql(string sql, params object[] args) => sql?.FormatOdbc(args);
static FreeSql.Odbc.Default.OdbcAdo _customAdo = new FreeSql.Odbc.Default.OdbcAdo();
public override string FormatSql(string sql, params object[] args) => (_orm?.Ado as OdbcAdo)?.Addslashes(sql, args) ?? _customAdo.Addslashes(sql, args);
public override string QuoteSqlName(params string[] name)
{
if (name.Length == 1)

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -37,15 +37,6 @@
internal static string FormatOdbcPostgreSQL(this string that, params object[] args) => _odbcPostgreSQLAdo.Addslashes(that, args);
static FreeSql.Odbc.PostgreSQL.OdbcPostgreSQLAdo _odbcPostgreSQLAdo = new FreeSql.Odbc.PostgreSQL.OdbcPostgreSQLAdo();
/// <summary>
/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
/// </summary>
/// <param name="that"></param>
/// <param name="args"></param>
/// <returns></returns>
internal static string FormatOdbc(this string that, params object[] args) => _odbcAdo.Addslashes(that, args);
static FreeSql.Odbc.Default.OdbcAdo _odbcAdo = new FreeSql.Odbc.Default.OdbcAdo();
/// <summary>
/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
/// </summary>

View File

@ -201,7 +201,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname);
if (istmpatler == false)
{
var existsPrimary = LocalExecuteScalar(tbname[0], _commonUtils.FormatSql(" select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname));
var existsPrimary = LocalExecuteScalar(tbname[0], _commonUtils.FormatSql(" select 1 from information_schema.columns where table_schema={0} and table_name={1} and column_key = 'PRI' limit 1", tbname));
foreach (var tbcol in tb.ColumnsByPosition)
{
var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1;

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.RegularExpressions;
namespace FreeSql.Odbc.SqlServer
{
@ -44,7 +45,7 @@ namespace FreeSql.Odbc.SqlServer
if (_limit > 0 || _skip > 0)
{
if (string.IsNullOrEmpty(_orderby))
if (string.IsNullOrEmpty(_orderby) && (_limit > 1 || _skip > 0)) //TOP 1 不自动 order by
{
if (string.IsNullOrEmpty(_groupby))
{
@ -63,13 +64,15 @@ namespace FreeSql.Odbc.SqlServer
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
for (var a = 0; a < tbsfrom.Length; a++)
{
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias);
var alias = LocalGetTableAlias(tbsfrom[a].Table.Type, tbUnion[tbsfrom[a].Table.Type], tbsfrom[a].Alias, _aliasRule);
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(alias);
if (tbsjoin.Length > 0)
{
//如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1
for (var b = 1; b < tbsfrom.Length; b++)
{
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias);
alias = LocalGetTableAlias(tbsfrom[b].Table.Type, tbUnion[tbsfrom[b].Table.Type], tbsfrom[b].Alias, _aliasRule);
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(alias);
if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1");
else
@ -110,7 +113,8 @@ namespace FreeSql.Odbc.SqlServer
sb.Append(" \r\nRIGHT JOIN ");
break;
}
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition);
var alias = LocalGetTableAlias(tb.Table.Type, tbUnion[tb.Table.Type], tb.Alias, _aliasRule);
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition);
if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade);
if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")");
}
@ -176,13 +180,15 @@ namespace FreeSql.Odbc.SqlServer
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
for (var a = 0; a < tbsfrom.Length; a++)
{
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias);
var alias = LocalGetTableAlias(tbsfrom[a].Table.Type, tbUnion[tbsfrom[a].Table.Type], tbsfrom[a].Alias, _aliasRule);
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(alias);
if (tbsjoin.Length > 0)
{
//如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1
for (var b = 1; b < tbsfrom.Length; b++)
{
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias);
alias = LocalGetTableAlias(tbsfrom[b].Table.Type, tbUnion[tbsfrom[b].Table.Type], tbsfrom[b].Alias, _aliasRule);
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(alias);
if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1");
else
@ -223,7 +229,8 @@ namespace FreeSql.Odbc.SqlServer
sb.Append(" \r\nRIGHT JOIN ");
break;
}
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition);
var alias = LocalGetTableAlias(tb.Table.Type, tbUnion[tb.Table.Type], tb.Alias, _aliasRule);
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition);
if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade);
if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")");
}
@ -271,6 +278,17 @@ namespace FreeSql.Odbc.SqlServer
}
#endregion
static string LocalGetTableAlias(Type entityType, string tbname, string alias, Func<Type, string, string> aliasRule)
{
if (aliasRule != null)
{
alias = aliasRule(entityType, alias);
if (tbname.IndexOf(' ') != -1) //还可以这样select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList()
alias = Regex.Replace(alias, @" With\([^\)]+\)", ""); //替换 WithLock、WithIndex
}
return alias;
}
public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override ISelect<T1, T2> From<T2>(Expression<Func<ISelectFromExpression<T1>, T2, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect<T1, T2>(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3> From<T2, T3>(Expression<Func<ISelectFromExpression<T1>, T2, T3, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect<T1, T2, T3>(_orm, _commonUtils, _commonExpression, null); OdbcSqlServerSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -15,7 +15,7 @@
<Title>$(AssemblyName)</Title>
<IsPackable>true</IsPackable>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.RegularExpressions;
namespace FreeSql.SqlServer.Curd
{
@ -44,7 +45,7 @@ namespace FreeSql.SqlServer.Curd
if (_limit > 0 || _skip > 0)
{
if (string.IsNullOrEmpty(_orderby))
if (string.IsNullOrEmpty(_orderby) && (_limit > 1 || _skip > 0)) //TOP 1 不自动 order by
{
if (string.IsNullOrEmpty(_groupby))
{
@ -63,13 +64,15 @@ namespace FreeSql.SqlServer.Curd
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
for (var a = 0; a < tbsfrom.Length; a++)
{
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias);
var alias = LocalGetTableAlias(tbsfrom[a].Table.Type, tbUnion[tbsfrom[a].Table.Type], tbsfrom[a].Alias, _aliasRule);
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(alias);
if (tbsjoin.Length > 0)
{
//如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1
for (var b = 1; b < tbsfrom.Length; b++)
{
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias);
alias = LocalGetTableAlias(tbsfrom[b].Table.Type, tbUnion[tbsfrom[b].Table.Type], tbsfrom[b].Alias, _aliasRule);
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(alias);
if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1");
else
@ -110,7 +113,8 @@ namespace FreeSql.SqlServer.Curd
sb.Append(" \r\nRIGHT JOIN ");
break;
}
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition);
var alias = LocalGetTableAlias(tb.Table.Type, tbUnion[tb.Table.Type], tb.Alias, _aliasRule);
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition);
if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade);
if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")");
}
@ -176,13 +180,15 @@ namespace FreeSql.SqlServer.Curd
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
for (var a = 0; a < tbsfrom.Length; a++)
{
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias);
var alias = LocalGetTableAlias(tbsfrom[a].Table.Type, tbUnion[tbsfrom[a].Table.Type], tbsfrom[a].Alias, _aliasRule);
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(alias);
if (tbsjoin.Length > 0)
{
//如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1
for (var b = 1; b < tbsfrom.Length; b++)
{
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias);
alias = LocalGetTableAlias(tbsfrom[b].Table.Type, tbUnion[tbsfrom[b].Table.Type], tbsfrom[b].Alias, _aliasRule);
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(alias);
if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1");
else
@ -223,7 +229,8 @@ namespace FreeSql.SqlServer.Curd
sb.Append(" \r\nRIGHT JOIN ");
break;
}
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition);
var alias = LocalGetTableAlias(tb.Table.Type, tbUnion[tb.Table.Type], tb.Alias, _aliasRule);
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition);
if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade);
if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")");
}
@ -271,6 +278,17 @@ namespace FreeSql.SqlServer.Curd
}
#endregion
static string LocalGetTableAlias(Type entityType, string tbname, string alias, Func<Type, string, string> aliasRule)
{
if (aliasRule != null)
{
alias = aliasRule(entityType, alias);
if (tbname.IndexOf(' ') != -1) //还可以这样select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList()
alias = Regex.Replace(alias, @" With\([^\)]+\)", ""); //替换 WithLock、WithIndex
}
return alias;
}
public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) {
if (FreeSqlSqlServerGlobalExtensions._dicSetGlobalSelectWithLock.TryGetValue(orm.Ado.Identifier, out var tryval))
this.WithLock(tryval.Item1, tryval.Item2);

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<DelaySign>false</DelaySign>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>
@ -26,7 +26,7 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net451'">
<PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'net60' or '$(TargetFramework)' == 'net50'">
<PackageReference Include="Microsoft.Data.SqlClient" Version="2.1.4" />

View File

@ -4,6 +4,7 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using FreeSql.Internal.CommonProvider;
#if microsoft
using Microsoft.Data.SqlClient;
#else
@ -31,10 +32,74 @@ public static partial class FreeSqlSqlServerGlobalExtensions
/// <param name="lockType"></param>
/// <param name="rule">多表查询时的锁规则</param>
/// <returns></returns>
public static ISelect<T> WithLock<T>(this ISelect<T> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null)
=> rule == null ?
that.AsAlias((type, old) => $"{old} With({lockType.ToString()})") :
that.AsAlias((type, old) => rule.TryGetValue(type, out var trybool) && trybool ? $"{old} With({lockType.ToString()})" : old);
public static ISelect<T> WithLock<T>(this ISelect<T> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2> WithLock<T1, T2>(this ISelect<T1, T2> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2, T3> WithLock<T1, T2, T3>(this ISelect<T1, T2, T3> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class where T3 : class => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2, T3, T4> WithLock<T1, T2, T3, T4>(this ISelect<T1, T2, T3, T4> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2, T3, T4, T5> WithLock<T1, T2, T3, T4, T5>(this ISelect<T1, T2, T3, T4, T5> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2, T3, T4, T5, T6> WithLock<T1, T2, T3, T4, T5, T6>(this ISelect<T1, T2, T3, T4, T5, T6> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7> WithLock<T1, T2, T3, T4, T5, T6, T7>(this ISelect<T1, T2, T3, T4, T5, T6, T7> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8> WithLock<T1, T2, T3, T4, T5, T6, T7, T8>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> WithLock<T1, T2, T3, T4, T5, T6, T7, T8, T9>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> WithLock<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> WithLock<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> WithLock<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> WithLock<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> WithLock<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> WithLock<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class => LocalWithLock(that, lockType, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> WithLock<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> that, SqlServerLock lockType = SqlServerLock.NoLock, Dictionary<Type, bool> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class => LocalWithLock(that, lockType, rule);
static TReturn LocalWithLock<TReturn>(TReturn query, SqlServerLock lockType, Dictionary<Type, bool> rule)
{
var selectProvider = query as Select0Provider;
var oldalias = selectProvider._aliasRule;
selectProvider._aliasRule = (type, old) =>
{
if (oldalias != null) old = oldalias(type, old);
if (rule == null) return LocalAppendWithString(old, lockType.ToString());
return rule.TryGetValue(type, out var trybool) && trybool ? LocalAppendWithString(old, lockType.ToString()) : old;
};
return query;
}
/// <summary>
/// SqkServer with(index) 强制索引
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="that"></param>
/// <param name="rule"></param>
/// <returns></returns>
public static ISelect<T> WithIndex<T>(this ISelect<T> that, string indexName, Dictionary<Type, string> rule = null) => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2> WithIndex<T1, T2>(this ISelect<T1, T2> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2, T3> WithIndex<T1, T2, T3>(this ISelect<T1, T2, T3> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class where T3 : class => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2, T3, T4> WithIndex<T1, T2, T3, T4>(this ISelect<T1, T2, T3, T4> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2, T3, T4, T5> WithIndex<T1, T2, T3, T4, T5>(this ISelect<T1, T2, T3, T4, T5> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2, T3, T4, T5, T6> WithIndex<T1, T2, T3, T4, T5, T6>(this ISelect<T1, T2, T3, T4, T5, T6> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7> WithIndex<T1, T2, T3, T4, T5, T6, T7>(this ISelect<T1, T2, T3, T4, T5, T6, T7> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8> WithIndex<T1, T2, T3, T4, T5, T6, T7, T8>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> WithIndex<T1, T2, T3, T4, T5, T6, T7, T8, T9>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> WithIndex<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> WithIndex<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> WithIndex<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> WithIndex<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> WithIndex<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> WithIndex<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class => LocalWithIndex(that, indexName, rule);
public static ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> WithIndex<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(this ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> that, string indexName, Dictionary<Type, string> rule = null) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class => LocalWithIndex(that, indexName, rule);
static TReturn LocalWithIndex<TReturn>(TReturn query, string indexName, Dictionary<Type, string> rule)
{
if (string.IsNullOrWhiteSpace(indexName)) return query;
var selectProvider = query as Select0Provider;
var oldalias = selectProvider._aliasRule;
selectProvider._aliasRule = (type, old) =>
{
if (oldalias != null) old = oldalias(type, old);
if (type == selectProvider._tables[0].Table.Type) return LocalAppendWithString(old, $"index={indexName}");
if (rule == null) return old;
return rule.TryGetValue(type, out var tryidxName) && string.IsNullOrWhiteSpace(tryidxName) == false ? LocalAppendWithString(old, $"index={tryidxName}") : old;
};
return query;
}
static string LocalAppendWithString(string old, string str) => old?.Contains(" With(") == true ? old.Replace(" With(", $" With({str}, ") : $"{old} With({str})";
/// <summary>
/// 设置全局 SqlServer with(nolock) 查询

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>
@ -26,7 +26,7 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'net45' and '$(TargetFramework)' != 'net40'">
<PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
</ItemGroup>
<ItemGroup>

View File

@ -58,6 +58,22 @@ namespace FreeSql.Sqlite.Curd
return ret;
}
public override string ToSql()
{
if (_table.Columns.Count == 1 && _table.ColumnsByPosition[0].Attribute.IsIdentity)
{
var sb = new StringBuilder();
var didx = 0;
foreach (var d in _source)
{
if (didx++ > 0) sb.Append(";\r\n");
sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" DEFAULT VALUES");
}
return sb.ToString();
}
return base.ToSql();
}
#if net40
#else
public override Task<int> ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken);

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -76,7 +76,7 @@ namespace FreeSql.Sqlite
{
_connectionString = value ?? "";
var minPoolSize = 0;
var minPoolSize = 1;
var pattern = @"Min\s*pool\s*size\s*=\s*(\d+)";
var m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
if (m.Success)

View File

@ -136,7 +136,7 @@ namespace FreeSql.Sqlite
{
sb.Append("CREATE ");
if (uk.IsUnique) sb.Append("UNIQUE ");
sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tbname[1]).Append("(");
sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(tbname[0], ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tbname[1]).Append("(");
foreach (var tbcol in uk.Columns)
{
sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name));
@ -213,7 +213,7 @@ namespace FreeSql.Sqlite
{
if (string.Concat(dbIndex[3]) == "pk") continue;
var dbIndexesColumns = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA {_commonUtils.QuoteSqlName(tbtmp[0])}.INDEX_INFO({dbIndex[1]})");
var dbIndexesSql = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, $" SELECT sql FROM sqlite_master WHERE name = '{dbIndex[1]}'"));
var dbIndexesSql = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, $" SELECT sql FROM {_commonUtils.QuoteSqlName(tbtmp[0])}.sqlite_master WHERE name = '{dbIndex[1]}'"));
foreach (var dbcolumn in dbIndexesColumns)
{
var dbcolumnName = string.Concat(dbcolumn[2]);
@ -292,7 +292,7 @@ namespace FreeSql.Sqlite
{
sb.Append("CREATE ");
if (uk.IsUnique) sb.Append("UNIQUE ");
sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON \"").Append(tablenameOnlyTb).Append("\"(");
sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(tbname[0], ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON \"").Append(tablenameOnlyTb).Append("\"(");
foreach (var tbcol in uk.Columns)
{
sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name));

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<Version>3.2.683-preview20221101</Version>
<Version>3.2.684-preview20221124</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -209,7 +209,8 @@ constantine,
[JohnZhou2020](https://github.com/JohnZhou2020),
[mafeng8](https://github.com/mafeng8),
[VicBilibily](https://github.com/VicBilibily),
[Soar](https://github.com/sgf) etc.
[Soar](https://github.com/sgf),
[quzhen91](https://github.com/quzhen91) etc.
## 💕 Donation

View File

@ -210,8 +210,8 @@ constantine,
[JohnZhou2020](https://github.com/JohnZhou2020),
[mafeng8](https://github.com/mafeng8),
[VicBilibily](https://github.com/VicBilibily),
[Soar](https://github.com/sgf) 等。
[Soar](https://github.com/sgf),
[quzhen91](https://github.com/quzhen91) 等。
## 💕 Donation (捐赠)