我的问题是
我可以在没有IQueryble<T>
的情况下构建DbSet<T>
吗?
然后将IQueryable<T>
传递到将IQueryable<T>
附加到DbSet<T>
的方法上?
示例:
public class Querying<T>
{
public T BuildQuery()
{
return Enumerable.Empty<T>().AsQueryable().Where(...);
}
}
public class DatabaseContext<T>:DbContext
{
DbSet<T> _set;
public List<T> ExecuteQuery(Querying<T> query)
{
return _set.AttachQuery(query.BuildQuery()).ToList();
}
}
答案 0 :(得分:0)
using System;
using System.Linq;
using System.Linq.Expressions;
namespace QueryTest
{
internal static class Program
{
private class ReplaceConstantVisitor : ExpressionVisitor
{
public object OldValue { get; }
public object NewValue { get; }
public ReplaceConstantVisitor(object oldValue, object newValue)
{
OldValue = oldValue;
NewValue = newValue;
}
protected override Expression VisitConstant(ConstantExpression node)
{
if (node.Value == OldValue)
{
return Expression.Constant(NewValue);
}
return base.VisitConstant(node);
}
}
public static IQueryable<TQuery> ReplaceSource<TQuery, TSource>(this IQueryable<TQuery> query, IQueryable<TSource> source)
{
var exp = query.Expression;
while (exp is MethodCallExpression m)
{
exp = m.Arguments[0];
}
if (!(exp is ConstantExpression oldSource))
{
throw new ArgumentException();
}
var newExp = new ReplaceConstantVisitor(oldSource.Value, source).Visit(query.Expression);
return source.Provider.CreateQuery<TQuery>(newExp);
}
internal static void Main(string[] args)
{
var oldSource = new int[] { }.AsQueryable();
var query =
from i in oldSource
where i > 5
select $"{i * 2}";
var newSource = new int[] { 1, 3, 5, 7, 9 }.AsQueryable();
var newQuery = query.ReplaceSource(newSource);
Console.WriteLine(string.Join(", ", newQuery)); //14, 18
}
}
}