mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 10:42:52 +08:00
Merge branch 'master' of https://github.com/dotnetcore/FreeSql
This commit is contained in:
commit
3c991178c6
@ -11,7 +11,7 @@
|
||||
<!--
|
||||
经常出于版本交叉问题,暂时关闭,在每个项目上设置版本号
|
||||
<PropertyGroup>
|
||||
<Version>3.2.683-preview20221101</Version>
|
||||
<Version>3.2.684-preview20221124</Version>
|
||||
</PropertyGroup>
|
||||
-->
|
||||
|
||||
|
@ -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 抖店实时销售金额表
|
||||
|
@ -168,11 +168,8 @@ 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)));
|
||||
return await InsertAsync(entity, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual Task<int> UpdateAsync(TEntity entity, CancellationToken cancellationToken = default) => UpdateAsync(new[] { entity }, cancellationToken);
|
||||
@ -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)
|
||||
|
@ -221,11 +221,8 @@ 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)));
|
||||
return Insert(entity);
|
||||
}
|
||||
|
||||
public virtual int Update(TEntity entity) => Update(new[] { entity });
|
||||
@ -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)
|
||||
|
@ -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'">
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
.Where(a => a.PropertyType.IsGenericType &&
|
||||
a.PropertyType == typeof(DbSet<>).MakeGenericType(a.PropertyType.GetGenericArguments()[0])).ToArray(),
|
||||
false));
|
||||
if (dicval.Item2 == false)
|
||||
var isOnModelCreating = false;
|
||||
if (_dicGetDbSetProps.TryGetValue(thisType, out var dicval) == false)
|
||||
{
|
||||
if (_dicGetDbSetProps.TryUpdate(thisType, NativeTuple.Create(dicval.Item1, true), dicval))
|
||||
OnModelCreating(OrmOriginal.CodeFirst);
|
||||
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);
|
||||
_dicGetDbSetProps.TryAdd(thisType, dicval);
|
||||
isOnModelCreating = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isOnModelCreating)
|
||||
OnModelCreating(OrmOriginal.CodeFirst);
|
||||
|
||||
foreach (var prop in dicval.Item1)
|
||||
{
|
||||
|
@ -98,58 +98,64 @@ namespace FreeSql
|
||||
}
|
||||
};
|
||||
|
||||
while (_prevCommands.Any() || states.Any())
|
||||
try
|
||||
{
|
||||
var info = _prevCommands.Any() ? _prevCommands.Dequeue() : null;
|
||||
if (oldinfo == null) oldinfo = info;
|
||||
var isLiveUpdate = false;
|
||||
flagFuncUpdateLaststate = false;
|
||||
|
||||
if (_prevCommands.Any() == false && states.Any() ||
|
||||
info != null && oldinfo.changeType != info.changeType ||
|
||||
info != null && oldinfo.stateType != info.stateType ||
|
||||
info != null && oldinfo.entityType != info.entityType)
|
||||
while (_prevCommands.Any() || states.Any())
|
||||
{
|
||||
var info = _prevCommands.Any() ? _prevCommands.Dequeue() : null;
|
||||
if (oldinfo == null) oldinfo = info;
|
||||
var isLiveUpdate = false;
|
||||
flagFuncUpdateLaststate = false;
|
||||
|
||||
if (info != null && oldinfo.changeType == info.changeType && oldinfo.stateType == info.stateType && oldinfo.entityType == info.entityType)
|
||||
if (_prevCommands.Any() == false && states.Any() ||
|
||||
info != null && oldinfo.changeType != info.changeType ||
|
||||
info != null && oldinfo.stateType != info.stateType ||
|
||||
info != null && oldinfo.entityType != info.entityType)
|
||||
{
|
||||
|
||||
if (info != null && oldinfo.changeType == info.changeType && oldinfo.stateType == info.stateType && oldinfo.entityType == info.entityType)
|
||||
{
|
||||
//最后一个,合起来发送
|
||||
states.Add(info.state);
|
||||
info = null;
|
||||
}
|
||||
|
||||
switch (oldinfo.changeType)
|
||||
{
|
||||
case EntityChangeType.Insert:
|
||||
await funcInsert();
|
||||
break;
|
||||
case EntityChangeType.Delete:
|
||||
await funcDelete();
|
||||
break;
|
||||
}
|
||||
isLiveUpdate = true;
|
||||
}
|
||||
|
||||
if (isLiveUpdate || oldinfo.changeType == EntityChangeType.Update)
|
||||
{
|
||||
if (states.Any())
|
||||
{
|
||||
await funcUpdate(isLiveUpdate);
|
||||
if (info?.changeType == EntityChangeType.Update)
|
||||
flagFuncUpdateLaststate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
//最后一个,合起来发送
|
||||
states.Add(info.state);
|
||||
info = null;
|
||||
oldinfo = info;
|
||||
|
||||
if (flagFuncUpdateLaststate && oldinfo.changeType == EntityChangeType.Update) //马上与上个元素比较
|
||||
await funcUpdate(isLiveUpdate);
|
||||
}
|
||||
|
||||
switch (oldinfo.changeType)
|
||||
{
|
||||
case EntityChangeType.Insert:
|
||||
await funcInsert();
|
||||
break;
|
||||
case EntityChangeType.Delete:
|
||||
await funcDelete();
|
||||
break;
|
||||
}
|
||||
isLiveUpdate = true;
|
||||
}
|
||||
|
||||
if (isLiveUpdate || oldinfo.changeType == EntityChangeType.Update)
|
||||
{
|
||||
if (states.Any())
|
||||
{
|
||||
await funcUpdate(isLiveUpdate);
|
||||
if (info?.changeType == EntityChangeType.Update)
|
||||
flagFuncUpdateLaststate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
states.Add(info.state);
|
||||
oldinfo = info;
|
||||
|
||||
if (flagFuncUpdateLaststate && oldinfo.changeType == EntityChangeType.Update) //马上与上个元素比较
|
||||
await funcUpdate(isLiveUpdate);
|
||||
}
|
||||
}
|
||||
isFlushCommanding = false;
|
||||
finally
|
||||
{
|
||||
isFlushCommanding = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -113,58 +113,64 @@ namespace FreeSql
|
||||
}
|
||||
};
|
||||
|
||||
while (_prevCommands.Any() || states.Any())
|
||||
try
|
||||
{
|
||||
var info = _prevCommands.Any() ? _prevCommands.Dequeue() : null;
|
||||
if (oldinfo == null) oldinfo = info;
|
||||
var isLiveUpdate = false;
|
||||
flagFuncUpdateLaststate = false;
|
||||
|
||||
if (_prevCommands.Any() == false && states.Any() ||
|
||||
info != null && oldinfo.changeType != info.changeType ||
|
||||
info != null && oldinfo.stateType != info.stateType ||
|
||||
info != null && oldinfo.entityType != info.entityType)
|
||||
while (_prevCommands.Any() || states.Any())
|
||||
{
|
||||
var info = _prevCommands.Any() ? _prevCommands.Dequeue() : null;
|
||||
if (oldinfo == null) oldinfo = info;
|
||||
var isLiveUpdate = false;
|
||||
flagFuncUpdateLaststate = false;
|
||||
|
||||
if (info != null && oldinfo.changeType == info.changeType && oldinfo.stateType == info.stateType && oldinfo.entityType == info.entityType)
|
||||
if (_prevCommands.Any() == false && states.Any() ||
|
||||
info != null && oldinfo.changeType != info.changeType ||
|
||||
info != null && oldinfo.stateType != info.stateType ||
|
||||
info != null && oldinfo.entityType != info.entityType)
|
||||
{
|
||||
|
||||
if (info != null && oldinfo.changeType == info.changeType && oldinfo.stateType == info.stateType && oldinfo.entityType == info.entityType)
|
||||
{
|
||||
//最后一个,合起来发送
|
||||
states.Add(info.state);
|
||||
info = null;
|
||||
}
|
||||
|
||||
switch (oldinfo.changeType)
|
||||
{
|
||||
case EntityChangeType.Insert:
|
||||
funcInsert();
|
||||
break;
|
||||
case EntityChangeType.Delete:
|
||||
funcDelete();
|
||||
break;
|
||||
}
|
||||
isLiveUpdate = true;
|
||||
}
|
||||
|
||||
if (isLiveUpdate || oldinfo.changeType == EntityChangeType.Update)
|
||||
{
|
||||
if (states.Any())
|
||||
{
|
||||
funcUpdate(isLiveUpdate);
|
||||
if (info?.changeType == EntityChangeType.Update)
|
||||
flagFuncUpdateLaststate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
//最后一个,合起来发送
|
||||
states.Add(info.state);
|
||||
info = null;
|
||||
oldinfo = info;
|
||||
|
||||
if (flagFuncUpdateLaststate && oldinfo.changeType == EntityChangeType.Update) //马上与上个元素比较
|
||||
funcUpdate(isLiveUpdate);
|
||||
}
|
||||
|
||||
switch (oldinfo.changeType)
|
||||
{
|
||||
case EntityChangeType.Insert:
|
||||
funcInsert();
|
||||
break;
|
||||
case EntityChangeType.Delete:
|
||||
funcDelete();
|
||||
break;
|
||||
}
|
||||
isLiveUpdate = true;
|
||||
}
|
||||
|
||||
if (isLiveUpdate || oldinfo.changeType == EntityChangeType.Update)
|
||||
{
|
||||
if (states.Any())
|
||||
{
|
||||
funcUpdate(isLiveUpdate);
|
||||
if (info?.changeType == EntityChangeType.Update)
|
||||
flagFuncUpdateLaststate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
states.Add(info.state);
|
||||
oldinfo = info;
|
||||
|
||||
if (flagFuncUpdateLaststate && oldinfo.changeType == EntityChangeType.Update) //马上与上个元素比较
|
||||
funcUpdate(isLiveUpdate);
|
||||
}
|
||||
}
|
||||
isFlushCommanding = false;
|
||||
finally
|
||||
{
|
||||
isFlushCommanding = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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<string, object>
|
||||
/// </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)
|
||||
{
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -1336,25 +1336,28 @@ 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());
|
||||
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);
|
||||
var refCol = Expression.MakeMemberAccess(otmExpParm1, tbref2.Properties[tbref.RefColumns[0].CsName]);
|
||||
subSelect.Where(Expression.Lambda<Func<TNavigate, bool>>(
|
||||
Expression.Call(null, containsMethod, arrExp, refCol), otmExpParm1));
|
||||
|
||||
if (isAsync)
|
||||
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);
|
||||
var refCol = Expression.MakeMemberAccess(otmExpParm1, tbref2.Properties[tbref.RefColumns[0].CsName]);
|
||||
subSelect.Where(Expression.Lambda<Func<TNavigate, bool>>(
|
||||
Expression.Call(null, containsMethod, arrExp, refCol), otmExpParm1));
|
||||
|
||||
if (isAsync)
|
||||
{
|
||||
#if net40
|
||||
#else
|
||||
if (selectExp == null) subList = await subSelect.ToListAsync(true, cancellationToken);
|
||||
else subList = await subSelect.ToListAsync<TNavigate>(selectExp, cancellationToken);
|
||||
if (selectExp == null) subList = await subSelect.ToListAsync(true, cancellationToken);
|
||||
else subList = await subSelect.ToListAsync<TNavigate>(selectExp, cancellationToken);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selectExp == null) subList = subSelect.ToList(true);
|
||||
else subList = subSelect.ToList<TNavigate>(selectExp);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -2458,6 +2458,7 @@ namespace FreeSql.Internal
|
||||
}
|
||||
if (sidx < sql.Length && sql[sidx] == '\'')
|
||||
{
|
||||
sidx++;
|
||||
startLength += 2;
|
||||
continue;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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) ||
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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" />
|
||||
|
@ -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) 查询
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 (捐赠)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user