Skip to content

Instantly share code, notes, and snippets.

@to11mtm
Last active March 2, 2025 23:23
Show Gist options
  • Save to11mtm/d59326855492418fc3b8c8cbdecefc77 to your computer and use it in GitHub Desktop.
Save to11mtm/d59326855492418fc3b8c8cbdecefc77 to your computer and use it in GitHub Desktop.
Reddit EF Repository pattern stuff
public static class WatCache<T> where T : class
{
private static ConcurrentDictionary<object, Action<T,Guid>> _cache = new();
public static Action<T, Guid> Get(Expression<Func<T, object>> selector) => _cache.GetOrAdd(selector, sel =>
{
var expr = (Expression<Func<T, object>>)sel;
var member = expr.Body as MemberExpression;
var prop = member!.Member as PropertyInfo;
var ep = Expression.Parameter(typeof(T), "entity");
var gp = Expression.Parameter(typeof(Guid), "id");
var assignExp = Expression.Assign(Expression.Property(ep, prop!), gp);
var lambda = Expression.Lambda<Action<T, Guid>>(assignExp, ep, gp);
return lambda.Compile();
});
}
public static class Wat
{
public static async Task AddCollectionEntry<TCollectionType>(this DbContext _context, Guid parentId, Expression<Func<TCollectionType, object>> parentProperty, TCollectionType subEntity) where TCollectionType : class
{
WatCache<TCollectionType>.Get(parentProperty)(subEntity, parentId);
_context.Set<TCollectionType>().Add(subEntity);
await _context.SaveChangesAsync();
}
}
public static class WatCache<T> where T : class
{
private static ConcurrentDictionary<object, Action<T,Guid>> _cache = new();
private static Action<T,Guid> BuildArg<TGuid>(object mainObject)
{
var useConvert = (typeof(TGuid) == typeof(Guid?));
var expr = (Expression<Func<T, TGuid>>)mainObject;
var member = expr.Body as MemberExpression;
var prop = member!.Member as PropertyInfo;
var ep = Expression.Parameter(typeof(T), "entity");
var gp = Expression.Parameter(typeof(Guid), "id");
var assignExp = Expression.Assign(Expression.Property(ep, prop!),
useConvert ? Expression.Convert(gp, typeof(Guid?)) : gp);
var lambda = Expression.Lambda<Action<T, Guid>>(assignExp, ep, gp);
return lambda.Compile();
}
public static Action<T, Guid> Get(Expression<Func<T, Guid>> selector) =>
_cache.GetOrAdd(selector,
static s=> BuildArg<Guid>(s));
public static Action<T, Guid> Get(Expression<Func<T, Guid?>> selector) =>
_cache.GetOrAdd(selector,
static s=> BuildArg<Guid?>(s));
}
public static class Wat
{
public static async Task AddCollectionEntry<TCollectionType>(this DbContext _context, Guid parentId, Expression<Func<TCollectionType, Guid>> parentProperty, TCollectionType subEntity) where TCollectionType : class
{
WatCache<TCollectionType>.Get(parentProperty)(subEntity, parentId);
_context.Set<TCollectionType>().Add(subEntity);
await _context.SaveChangesAsync();
}
public static async Task AddCollectionEntry<TCollectionType>(this DbContext _context, Guid parentId, Expression<Func<TCollectionType, Guid?>> parentProperty, TCollectionType subEntity) where TCollectionType : class
{
WatCache<TCollectionType>.Get(parentProperty)(subEntity, parentId);
_context.Set<TCollectionType>().Add(subEntity);
await _context.SaveChangesAsync();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment