찾기로 필터링하는 쉬운 방법은 없습니다. 그러나 기능을 복제 할 수있는 가까운 방법을 찾았지만 솔루션에 대한 몇 가지 사항에 유의하십시오.
이 솔루션을 사용하면 .net-core의 기본 키를 몰라도 일반적으로 필터링 할 수 있습니다
찾기는 엔터티가 데이터베이스를 쿼리하기 전에 추적에있는 경우 엔터티를 가져 오기 때문에 근본적으로 다릅니다.
또한 사용자가 기본 키를 몰라도 개체별로 필터링 할 수 있습니다.
이 솔루션은 EntityFramework Core를위한 것입니다.
- 컨텍스트에 액세스해야합니다
기본 키로 필터링하는 데 도움이되는 몇 가지 확장 방법이 있습니다.
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));
}
이러한 확장 방법이 있으면 다음과 같이 필터링 할 수 있습니다.
query.FilterByPrimaryKey(this._context, id);