From 2510567a1066366c2916b995634edfb50ae0e251 Mon Sep 17 00:00:00 2001 From: David Lebee Date: Fri, 23 Nov 2018 10:17:52 -0600 Subject: [PATCH] helpers to find primary keys :) --- PoweredSoft.Data.Core/IDbContextFactory.cs | 5 +- .../DbContextFactory.cs | 53 +++++++++++++++++-- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/PoweredSoft.Data.Core/IDbContextFactory.cs b/PoweredSoft.Data.Core/IDbContextFactory.cs index 19ee05d..c683249 100644 --- a/PoweredSoft.Data.Core/IDbContextFactory.cs +++ b/PoweredSoft.Data.Core/IDbContextFactory.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -18,7 +19,9 @@ namespace PoweredSoft.Data.Core void Remove(object entity); int SaveChanges(); Task SaveChangesAsync(); - + IEnumerable GetKeyProperties(Type entityType); + IEnumerable>> GetKeyProperties(); + Task FirstOrDefaultAsync(IQueryable queryable, CancellationToken cancellationToken); Task FirstOrDefaultAsync(IQueryable queryable, Expression> predicate, CancellationToken cancellationToken); Task> ToListAsync(IQueryable queryable, CancellationToken cancellationToken); diff --git a/PoweredSoft.Data.EntityFrameworkCore/DbContextFactory.cs b/PoweredSoft.Data.EntityFrameworkCore/DbContextFactory.cs index 8bc09bf..82becf9 100644 --- a/PoweredSoft.Data.EntityFrameworkCore/DbContextFactory.cs +++ b/PoweredSoft.Data.EntityFrameworkCore/DbContextFactory.cs @@ -1,4 +1,5 @@ using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Internal; using PoweredSoft.Data.Core; using System; using System.Collections.Generic; @@ -28,11 +29,8 @@ namespace PoweredSoft.Data.EntityFrameworkCore public IQueryable GetQueryable(Type type) { - if (_setGenericMethod == null) - _setGenericMethod = typeof(DbContextFactory).GetMethods().FirstOrDefault(t => t.Name == nameof(GetQueryable) && t.ContainsGenericParameters); - - var gm = _setGenericMethod.MakeGenericMethod(type); - var ret = (IQueryable)gm.Invoke(this, new object[] { }); + var setSource = (IDbSetSource)this._context.GetType().GetProperty("SetSource", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_context); + var ret = (IQueryable)((IDbSetCache)this).GetOrAddSet(setSource, type); return ret; } @@ -44,6 +42,51 @@ namespace PoweredSoft.Data.EntityFrameworkCore public int SaveChanges() => _context.SaveChanges(); public async Task SaveChangesAsync() => await _context.SaveChangesAsync(); + public IEnumerable GetKeyProperties(Type entityType) + { + var key = _context.Model.FindEntityType(entityType).FindPrimaryKey(); + var keysProperties = key.Properties.Select(t => t.PropertyInfo); + return keysProperties; + } + + public IEnumerable>> GetKeyProperties() + { + 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>); + var lambda = Expression.Lambda(funcType, Expression.Convert(property, typeof(Object)), parameter); + return (Expression>)lambda; + }) + .ToList(); + return result; + } + + /* + // FOR EF6 when implemented. + public IEnumerable 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 FirstOrDefaultAsync(IQueryable queryable, CancellationToken cancellationToken = default(CancellationToken)) => queryable.FirstOrDefaultAsync(cancellationToken); public Task FirstOrDefaultAsync(IQueryable queryable, Expression> predicate, CancellationToken cancellationToken = default(CancellationToken)) => queryable.FirstOrDefaultAsync(predicate, cancellationToken); public Task> ToListAsync(IQueryable queryable, CancellationToken cancellationToken = default(CancellationToken)) => queryable.ToListAsync(cancellationToken);