helpers to find primary keys :)

This commit is contained in:
David Lebee 2018-11-23 10:17:52 -06:00
parent 0d1dca11bc
commit 2510567a10
2 changed files with 52 additions and 6 deletions

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Reflection;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -18,6 +19,8 @@ namespace PoweredSoft.Data.Core
void Remove(object entity); void Remove(object entity);
int SaveChanges(); int SaveChanges();
Task<int> SaveChangesAsync(); Task<int> SaveChangesAsync();
IEnumerable<PropertyInfo> GetKeyProperties(Type entityType);
IEnumerable<Expression<Func<TEntity, object>>> GetKeyProperties<TEntity>();
Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken); Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken);
Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken); Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken);

View File

@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
using PoweredSoft.Data.Core; using PoweredSoft.Data.Core;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -28,11 +29,8 @@ namespace PoweredSoft.Data.EntityFrameworkCore
public IQueryable GetQueryable(Type type) public IQueryable GetQueryable(Type type)
{ {
if (_setGenericMethod == null) var setSource = (IDbSetSource)this._context.GetType().GetProperty("SetSource", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_context);
_setGenericMethod = typeof(DbContextFactory).GetMethods().FirstOrDefault(t => t.Name == nameof(GetQueryable) && t.ContainsGenericParameters); var ret = (IQueryable)((IDbSetCache)this).GetOrAddSet(setSource, type);
var gm = _setGenericMethod.MakeGenericMethod(type);
var ret = (IQueryable)gm.Invoke(this, new object[] { });
return ret; return ret;
} }
@ -44,6 +42,51 @@ namespace PoweredSoft.Data.EntityFrameworkCore
public int SaveChanges() => _context.SaveChanges(); public int SaveChanges() => _context.SaveChanges();
public async Task<int> SaveChangesAsync() => await _context.SaveChangesAsync(); public async Task<int> SaveChangesAsync() => await _context.SaveChangesAsync();
public IEnumerable<PropertyInfo> GetKeyProperties(Type entityType)
{
var key = _context.Model.FindEntityType(entityType).FindPrimaryKey();
var keysProperties = key.Properties.Select(t => t.PropertyInfo);
return keysProperties;
}
public IEnumerable<Expression<Func<TEntity, object>>> GetKeyProperties<TEntity>()
{
var keyProps = GetKeyProperties(typeof(TEntity));
var parameter = Expression.Parameter(typeof(TEntity));
var result = keyProps
.Select(keyProp =>
{
var property = Expression.Property(parameter, keyProp);
var funcType = typeof(Expression<Func<TEntity, object>>);
var lambda = Expression.Lambda(funcType, Expression.Convert(property, typeof(Object)), parameter);
return (Expression<Func<TEntity, object>>)lambda;
})
.ToList();
return result;
}
/*
// FOR EF6 when implemented.
public IEnumerable<MemberExpression> GetKeyProperties(Type entityType)
{
foreach (PropertyInfo prop in entityType.GetProperties())
{
object[] attrs = prop.GetCustomAttributes(false);
foreach (object obj in attrs)
{
if (obj.GetType() == typeof(EdmScalarPropertyAttribute))
{
EdmScalarPropertyAttribute attr = (EdmScalarPropertyAttribute)obj;
if (attr.EntityKeyProperty)
keyList.Add(prop.Name);
}
}
}
}*/
public Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) => queryable.FirstOrDefaultAsync(cancellationToken); public Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) => queryable.FirstOrDefaultAsync(cancellationToken);
public Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken)) => queryable.FirstOrDefaultAsync(predicate, cancellationToken); public Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken)) => queryable.FirstOrDefaultAsync(predicate, cancellationToken);
public Task<List<T>> ToListAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) => queryable.ToListAsync(cancellationToken); public Task<List<T>> ToListAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) => queryable.ToListAsync(cancellationToken);