Tidak ada cara nyata yang mudah untuk menyaring dengan menemukan. Tetapi saya telah menemukan cara yang dekat untuk mereplikasi fungsi ini, tetapi harap perhatikan beberapa hal untuk solusi saya.
Solusi ini memungkinkan Anda untuk memfilter secara umum tanpa mengetahui kunci utama dalam .net-core
Temukan secara mendasar berbeda karena ia memperoleh entitas jika ada dalam pelacakan sebelum Meminta basis data.
Selain itu dapat memfilter berdasarkan Obyek sehingga pengguna tidak harus tahu kunci utama.
Solusi ini untuk EntityFramework Core.
- Ini membutuhkan akses ke konteksnya
Berikut adalah beberapa metode ekstensi untuk ditambahkan yang akan membantu Anda memfilter dengan kunci primer
public static IReadOnlyList<IProperty> GetPrimaryKeyProperties<T>(this DbContext dbContext)
{
return dbContext.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties;
}
//TODO Precompile expression so this doesn't happen everytime
public static Expression<Func<T, bool>> FilterByPrimaryKeyPredicate<T>(this DbContext dbContext, object[] id)
{
var keyProperties = dbContext.GetPrimaryKeyProperties<T>();
var parameter = Expression.Parameter(typeof(T), "e");
var body = keyProperties
// e => e.PK[i] == id[i]
.Select((p, i) => Expression.Equal(
Expression.Property(parameter, p.Name),
Expression.Convert(
Expression.PropertyOrField(Expression.Constant(new { id = id[i] }), "id"),
p.ClrType)))
.Aggregate(Expression.AndAlso);
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
public static Expression<Func<T, object[]>> GetPrimaryKeyExpression<T>(this DbContext context)
{
var keyProperties = context.GetPrimaryKeyProperties<T>();
var parameter = Expression.Parameter(typeof(T), "e");
var keyPropertyAccessExpression = keyProperties.Select((p, i) => Expression.Convert(Expression.Property(parameter, p.Name), typeof(object))).ToArray();
var selectPrimaryKeyExpressionBody = Expression.NewArrayInit(typeof(object), keyPropertyAccessExpression);
return Expression.Lambda<Func<T, object[]>>(selectPrimaryKeyExpressionBody, parameter);
}
public static IQueryable<TEntity> FilterByPrimaryKey<TEntity>(this DbSet<TEntity> dbSet, DbContext context, object[] id)
where TEntity : class
{
return FilterByPrimaryKey(dbSet.AsQueryable(), context, id);
}
public static IQueryable<TEntity> FilterByPrimaryKey<TEntity>(this IQueryable<TEntity> queryable, DbContext context, object[] id)
where TEntity : class
{
return queryable.Where(context.FilterByPrimaryKeyPredicate<TEntity>(id));
}
Setelah Anda memiliki metode ekstensi ini, Anda dapat memfilter seperti:
query.FilterByPrimaryKey(this._context, id);