वहाँ ढांचे में IQueryable<T>
के एक कार्यान्वयन है - MSDN: EnumerableQuery<T>
आप क्वेरी बनाने के लिए ग्राहक पर इसका उपयोग कर सकते हैं, तो आप IQueryable<T>.Expression
संपत्ति से पूरे अभिव्यक्ति ट्री मिल सकती है।
आपको यह देखने के लिए परीक्षण करना होगा कि यह अभिव्यक्ति वृक्ष Serializer के साथ काम करता है या नहीं।
var iQueryable = new EnumerableQuery<Model>(Enumerable.Empty<Model>());
var query = iQueryable.Include(...).Where(...).OrderBy(...);
var expressionTree = query.Expression;
आप अभिव्यक्ति को क्रमबद्ध कर सकते हैं, तार के पार इसे घुमा सकते हैं और फिर इसे deserialize कर सकते हैं।
तब समस्या यह है कि अभिव्यक्ति पेड़ EnumerableQuery<T>
पर आधारित है।
तो तुम से बदलने के लिए है कि अपने IQueryable<T>
स्रोत के साथ की जरूरत है अपने असली DbContext
यह एक बिट गंदा हो जाता है, लेकिन मैं एक कार्यान्वयन एक ExpressionVisitor:
IQueryable FixupExpressionTree(ObjectContext ctx, Type entityType, Expression expression)
{
var tObjectContext = ctx.GetType();
var mCreateObjectSetOpen = tObjectContext.GetMethod("CreateObjectSet", new Type[ 0 ]);
var mCreateObjectSetClosed = mCreateObjectSetOpen.MakeGenericMethod(entityType);
var objectQuery = (ObjectQuery) mCreateObjectSetClosed.Invoke(ctx, null);
var eFixed = new Visitor(objectQuery, entityType).Visit(expression);
var qFixed = ((IQueryable) objectQuery).Provider.CreateQuery(eFixed);
return qFixed;
}
और ExpressionVisitor
का उपयोग कर लिखा है स्वयं:
public class Visitor : ExpressionVisitor
{
ObjectQuery _Source = null;
Type _EntityType = null;
public Visitor(ObjectQuery source, Type entityType) { _Source = source; _EntityType = entityType; }
protected override Expression VisitConstant(ConstantExpression node)
{
if (!node.Type.Name.Contains("EnumerableQuery")) return base.VisitConstant(node);
var eConstantInstance = Expression.Constant(_Source);
var eConstantArgument = Expression.Constant(MergeOption.AppendOnly);
var tObjectQueryOpen = typeof(ObjectQuery<>);
var tObjectQueryClosed = tObjectQueryOpen.MakeGenericType(_EntityType);
var eMergeAsMethod = tObjectQueryClosed.GetMethod("MergeAs", BindingFlags.Instance | BindingFlags.NonPublic);
return Expression.Call(eConstantInstance, eMergeAsMethod, eConstantArgument);
}
}
कैली एनजी इस सीधे आगे है:
Type entityType = ...
Expression expression = ...
DbContext db = ...
ObjectContext ctx = ((IObjectContextAdapter) db).ObjectContext;
IQueryable query = FixupExpressionTree(ctx, entityType, expression);
मैं यह जानता हूँ अपने प्रश्न का उत्तर नहीं है, लेकिन अनुभव से, मैं यह कर नहीं होगा और बदले में समर्पित व्यापार सेवाओं लिखें। आप जटिलता जोड़ते हैं, और अपने ग्राहकों को सिस्टम को खराब प्रश्नों के साथ लाने की अनुमति देते हैं। –