Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions SubSonic/Extensions/Internal/Objects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ namespace SubSonic
/// </remarks>
internal static partial class InternalExtensions
{
public static bool IsIntGreaterThan(this object left, object right)
{
if (left is int _left)
{
if (right is int _right)
{
return _left > _right;
}
}

return false;
}
public static bool IsOfType<TType>(this object source)
{
return IsOfType(source, typeof(TType));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,7 @@ await Scope.Connection.OpenAsync(cancellationToken)
{
dbQuery.CleanUpParameters();

if (!(Scope.Connection is null))
{
Scope.Connection.Close();
}
Scope.Connection.Close();
}
}
}
Expand Down Expand Up @@ -217,7 +214,7 @@ public async IAsyncEnumerable<TResult> ExecuteAsync<TResult>([NotNull] Expressio
throw Error.ArgumentNull(nameof(query));
}

using SharedDbConnectionScope Scope = DbContext.ServiceProvider.GetService<SharedDbConnectionScope>();
using SharedDbConnectionScope Scope = DbContext.Current.UseSharedDbConnection();
IDbQuery dbQuery = ToQuery(query);

Type elementType = query.Type.GetQualifiedType();
Expand All @@ -226,8 +223,6 @@ public async IAsyncEnumerable<TResult> ExecuteAsync<TResult>([NotNull] Expressio

try
{
await Scope.Connection.OpenAsync(cancellationToken)
.ConfigureAwait(false);
if (isEntityModel)
{
using (DbDataReader reader = await Scope.Database
Expand Down Expand Up @@ -259,13 +254,11 @@ await Scope.Connection.OpenAsync(cancellationToken)
}
finally
{
if (Scope.Connection != null)
{
await Scope.Connection
.CloseAsync()
.ConfigureAwait(false);
}

#if NETSTANDARD2_1
await Scope.Connection.CloseAsync().ConfigureAwait(true);
#else
Scope.Connection.Close();
#endif
dbQuery.CleanUpParameters();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace SubSonic.Infrastructure.Builders
using Linq;
using Linq.Expressions;
using Logging;
using System.Globalization;

public partial class DbSqlQueryBuilder
{
Expand Down Expand Up @@ -146,10 +147,20 @@ public TResult Execute<TResult>(Expression expression)
{
if (BuildSelect(dbSelect, where) is DbSelectExpression select)
{
return Execute<TResult>(DbExpression.DbSelectAggregate(select, new[]
TResult result = Execute<TResult>(DbExpression.DbSelectAggregate(select, new[]
{
DbExpression.DbAggregate(typeof(TResult), AggregateType.Count, select.Columns.First(x => x.Property.IsPrimaryKey).Expression)
}));

if (select.Take is ConstantExpression take)
{
if (result.IsIntGreaterThan(take.Value))
{
return (TResult)Convert.ChangeType(take.Value, typeof(TResult), CultureInfo.InvariantCulture);
}
}

return result;
}
}

Expand Down
10 changes: 10 additions & 0 deletions SubSonic/Infrastructure/Database/DbDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ internal DbConnection CurrentSharedConnection

private static void DBSharedConnection_Disposed(object sender, EventArgs e)
{
dBSharedConnection?.Close();
dBSharedConnection = null;
}

Expand Down Expand Up @@ -270,6 +271,11 @@ public async Task<DbDataReader> ExecuteReaderAsync(IDbQuery dbQuery, Cancellatio

try
{
if (Scope.Connection.State != ConnectionState.Open)
{
Scope.Connection.Open();
}

return await cmd
.ExecuteReaderAsync(dbQuery.Behavior, cancellationToken)
.ConfigureAwait(false);
Expand All @@ -280,6 +286,10 @@ public async Task<DbDataReader> ExecuteReaderAsync(IDbQuery dbQuery, Cancellatio

throw;
}
finally
{

}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SubSonic.Infrastructure
Expand All @@ -10,23 +12,32 @@ public class SharedDbConnectionScope
: IConnectionScope
, IDisposable
{
[ThreadStatic]
private static Stack<SharedDbConnectionScope> __instances;
//[ThreadStatic]
private static Dictionary<int, Stack<SharedDbConnectionScope>> __db_instances;

private readonly DbDatabase dbDatabase;

public SharedDbConnectionScope(DbDatabase dbDatabase)
{
this.dbDatabase = dbDatabase ?? throw new ArgumentNullException(nameof(dbDatabase));
this.dbDatabase.InitializeSharedConnection();
this.threadId = Thread.CurrentThread.ManagedThreadId;

if (__instances == null)
if (__db_instances == null)
{
__instances = new Stack<SharedDbConnectionScope>();
__db_instances = new Dictionary<int, Stack<SharedDbConnectionScope>>();
}
__instances.Push(this);

if (!__db_instances.ContainsKey(threadId))
{
__db_instances[threadId] = new Stack<SharedDbConnectionScope>();
}

__db_instances[threadId].Push(this);
}

private readonly int threadId;

public DbConnection Connection => dbDatabase.CurrentSharedConnection;

public DbDatabase Database => dbDatabase;
Expand All @@ -41,11 +52,18 @@ protected virtual void Dispose(bool disposing)
{
if (disposing)
{
__instances?.Pop();
SharedDbConnectionScope scope = __db_instances[threadId].Pop();

Debug.Assert(scope.dbDatabase.CurrentSharedConnection.State == System.Data.ConnectionState.Closed, "open connection is being disposed.");

if (__db_instances[threadId]?.Count == 0)
{
__db_instances.Remove(threadId);
}

if(__instances?.Count == 0)
if (__db_instances.Count == 0)
{
this.dbDatabase.ResetSharedConnection();
scope.dbDatabase.ResetSharedConnection();
}

disposedValue = true;
Expand Down
13 changes: 7 additions & 6 deletions SubSonic/Linq/Expressions/DbSelectAggregateExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace SubSonic.Linq.Expressions
public class DbSelectAggregateExpression
: DbConstantExpression
{
private readonly DbSelectExpression select;
protected internal DbSelectAggregateExpression(DbSelectExpression select, IEnumerable<DbExpression> columns)
: base(
select.IsNullThrowArgumentNull(nameof(select)).QueryObject,
Expand All @@ -25,18 +24,20 @@ protected internal DbSelectAggregateExpression(DbSelectExpression select, IEnume

Columns = new ReadOnlyCollection<DbExpression>(columns.ToList());

this.select = select;
Select = select;
}

public DbSelectExpression Select { get; }

public ReadOnlyCollection<DbExpression> Columns { get; }

public bool IsCte => select.IsCte;
public bool IsCte => Select.IsCte;

public DbTableExpression From => select.From;
public DbTableExpression From => Select.From;

public Expression Where => select.Where;
public Expression Where => Select.Where;

public ReadOnlyCollection<Expression> GroupBy => select.GroupBy;
public ReadOnlyCollection<Expression> GroupBy => Select.GroupBy;

public string QueryText
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public partial class TSqlFormatter
: DbExpressionVisitor
{
[ThreadStatic]
private static Stack<TSqlFormatter> __instances;
private static Stack<TSqlFormatter> __formatter_instances;
private int depth = 0;
private readonly TextWriter writer;
private readonly ISqlContext context;
Expand All @@ -49,15 +49,15 @@ protected TSqlFormatter(TextWriter writer, ISqlContext context)
this.context = context ?? throw new ArgumentNullException(nameof(context));
this.provider = context.Provider ?? throw new InvalidOperationException();

if (__instances is null)
if (__formatter_instances is null)
{
__instances = new Stack<TSqlFormatter>();
__formatter_instances = new Stack<TSqlFormatter>();
}

__instances.Push(this);
__formatter_instances.Push(this);
}

protected static int IndentationWidth => __instances.Count;
protected static int IndentationWidth => __formatter_instances.Count;

protected bool IsNested { get; set; } = false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ protected virtual void Dispose(bool disposing)
{
if (disposing)
{
__instances.Pop();
__formatter_instances.Pop();

if(__instances.Count == 0)
if(__formatter_instances.Count == 0)
{
__instances = null;
__formatter_instances = null;
}
}

Expand Down
2 changes: 1 addition & 1 deletion SubSonic/SubSonic.Core.DataAccessLayer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<PackageTags>DAL;SqlServer;C#;.NetFramework;.NetCore;</PackageTags>
<Version>4.1.0-alpha.5</Version>
<Version>4.1.0-alpha.6</Version>
<PackageId>SubSonic.Core.DAL</PackageId>
<Company>SubSonic-Core</Company>
<PackageProjectUrl>https://github.com/SubSonic-Core/SubSonic/wiki</PackageProjectUrl>
Expand Down