Skip to content

Commit

Permalink
fix cache key
Browse files Browse the repository at this point in the history
  • Loading branch information
kinosang committed Apr 27, 2024
1 parent 30c4dbc commit 04df5a8
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public static class QueryContextExtensions
{
public static string? ToCacheKey<TEntity, TResult, T>(this QueryContext<TEntity, TResult, T> context)
where TEntity : class {
var query = context.Query.Expression.ToString();
var query = context.Repository.GetQueryString(context.Query);
return !string.IsNullOrWhiteSpace(query)
? string.Concat(query, "\x1e", typeof(T).Name).ToCacheKey()
: null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ public class EntityFrameworkCoreRepository<TContext, TEntity> : RepositoryBase<T
return DbSet.AsQueryable();
}

public override string? GetQueryString<T>(IQueryable<T> query) {
#if NET6_0_OR_GREATER
return query.ToQueryString();
#else
return query.ToSql();
#endif
}

public override async IAsyncEnumerable<TResult> ListAsync<TResult>(
Func<IQueryable<TEntity>, IQueryable<TResult>>? predicate,
[EnumeratorCancellation] CancellationToken ct = default) {
Expand Down
34 changes: 34 additions & 0 deletions src/Schemata.Entity.EntityFrameworkCore/QueryableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;

namespace Schemata.Entity.EntityFrameworkCore;

public static class QueryableExtensions
{
#if NETSTANDARD2_0 || NETSTANDARD2_1
public static string? ToSql<TEntity>(this IQueryable<TEntity> query)
{
using var enumerator = query.Provider.Execute<IEnumerable<TEntity>>(query.Expression).GetEnumerator();
var relationalCommandCache = enumerator.Private("_relationalCommandCache");
var selectExpression = relationalCommandCache?.Private<SelectExpression>("_selectExpression");
var factory = relationalCommandCache?.Private<IQuerySqlGeneratorFactory>("_querySqlGeneratorFactory");

var sqlGenerator = factory?.Create();
var command = sqlGenerator?.GetCommand(selectExpression);

var sql = command?.CommandText;
return sql;
}

private static object? Private(this object? obj, string privateField) {
return obj?.GetType().GetField(privateField, BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(obj);
}

private static T? Private<T>(this object obj, string privateField) {
return (T?)obj.GetType().GetField(privateField, BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(obj);
}
#endif
}
6 changes: 6 additions & 0 deletions src/Schemata.Entity.LinqToDB/LinQ2DbRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Humanizer;
using LinqToDB;
using LinqToDB.Data;
using LinqToDB.Linq;
using Schemata.Entity.Repository;
using Schemata.Entity.Repository.Advices;

Expand Down Expand Up @@ -47,6 +48,11 @@ public class LinQ2DbRepository<TContext, TEntity> : RepositoryBase<TEntity>
return Table.AsQueryable();
}

public override string? GetQueryString<T>(IQueryable<T> query) {
var expression = Internals.CreateExpressionQueryInstance<T>(Context, query.Expression);
return expression.ToString();
}

public override async IAsyncEnumerable<TResult> ListAsync<TResult>(
Func<IQueryable<TEntity>, IQueryable<TResult>>? predicate,
[EnumeratorCancellation] CancellationToken ct = default) {
Expand Down
2 changes: 2 additions & 0 deletions src/Schemata.Entity.Repository/IRepository`1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public interface IRepository<TEntity>

IQueryable<TEntity> AsQueryable();

string? GetQueryString<T>(IQueryable<T> query);

IAsyncEnumerable<TResult> ListAsync<TResult>(
Func<IQueryable<TEntity>, IQueryable<TResult>>? predicate,
CancellationToken ct = default);
Expand Down
5 changes: 4 additions & 1 deletion src/Schemata.Entity.Repository/RepositoryBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public abstract class RepositoryBase
var keyProperties = allProperties.Where(p => p.HasCustomAttribute<KeyAttribute>(true)).ToList();

if (keyProperties.Count == 0) {
var id = allProperties.FirstOrDefault(p => string.Equals(p.Name, "id", StringComparison.InvariantCultureIgnoreCase));
var id = allProperties.FirstOrDefault(p
=> string.Equals(p.Name, "id", StringComparison.InvariantCultureIgnoreCase));
if (id is not null) {
keyProperties.Add(id);
}
Expand Down Expand Up @@ -199,6 +200,8 @@ public abstract class RepositoryBase<TEntity> : RepositoryBase, IRepository<TEnt

public abstract IQueryable<TEntity> AsQueryable();

public abstract string? GetQueryString<T>(IQueryable<T> query);

public abstract IAsyncEnumerable<TResult> ListAsync<TResult>(
Func<IQueryable<TEntity>, IQueryable<TResult>>? predicate,
CancellationToken ct = default);
Expand Down

0 comments on commit 04df5a8

Please sign in to comment.