繁体   English   中英

构建 IQueryable<t> 然后将其附加到 DbSet<t></t></t>

[英]Building IQueryable<T> then attach it to DbSet<T>

我的问题是我可以在没有 DbSet<T> 的情况下构建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();
        }
    }
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
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM