2013-04-08 36 views
5

Tôi muốn sử dụng biểu thức LINQ trên phía máy khách, tuần tự hóa chúng và thực hiện chúng trên phía máy chủ.Trình bày cây nối tiếp

Đối với điều này tôi muốn sử dụng: http://expressiontree.codeplex.com/

Nhưng tôi muốn Execute họ agains một riêng WCF Gọi.

Điều đó có nghĩa tôi có một cuộc gọi trên WCF Side:

ImageDTO[] GetImages(XElement exp); 

bây giờ tôi muốn có một IQueryable trên Client Side (mà tôi có thể thực hiện LINQ Expressions), và tôi có một IQueryable trên serverside (từ lớp acess dữ liệu của tôi, mà tôi muốn thực hiện biểu thức tuần tự hóa).

Nhưng tôi không chắc chắn làm thế nào để làm điều này, và tôi không tìm thấy bất kỳ ví dụ ...

On Client Side tôi nghĩ rằng tôi nên thực hiện truy vấn trong một lớp, lớp này tôi nói trong Constructor sử dụng triển khai QueryProvider của tôi (từ nơi tôi gọi là Dịch vụ WCF). Nhưng tôi không chắc liệu điều này có đúng không ...

Có thể ai đó có thể trợ giúp với Ví dụ.

+1

Tôi biết điều này không phải là một câu trả lời cho câu hỏi của bạn, nhưng từ kinh nghiệm, tôi sẽ không làm điều này và thay vào đó viết các dịch vụ kinh doanh chuyên dụng. Bạn thêm tính phức tạp và cho phép khách hàng của bạn mang hệ thống xuống bằng truy vấn không hợp lệ. –

Trả lời

2

Có một thực hiện IQueryable<T> trong khuôn khổ - MSDN: EnumerableQuery<T>

Nếu bạn có thể sử dụng trên máy khách để xây dựng các truy vấn, bạn có thể lấy Tree toàn bộ biểu thức từ IQueryable<T>.Expression tài sản.

Bạn sẽ phải kiểm tra điều này để xem nó có hoạt động với Trình tạo chuỗi biểu thức cây đó không.

var iQueryable = new EnumerableQuery<Model>(Enumerable.Empty<Model>()); 

var query = iQueryable.Include(...).Where(...).OrderBy(...); 

var expressionTree = query.Expression; 

Sau đó, bạn có thể sắp xếp lại biểu thức, viết nó qua dây và sau đó deserialize nó.


Sau đó, vấn đề là cây biểu thức dựa trên EnumerableQuery<T>.

Vì vậy, bạn cần phải thay thế mà với nguồn IQueryable<T> của mình từ thực DbContext

Điều này được một chút lộn xộn, nhưng tôi đã viết một thực hiện sử dụng một 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 chính nó:

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); 
    } 
} 

Calli Điều này là thẳng về phía trước:

Type entityType = ... 
Expression expression = ... 
DbContext db = ... 

ObjectContext ctx = ((IObjectContextAdapter) db).ObjectContext; 

IQueryable query = FixupExpressionTree(ctx, entityType, expression); 
+0

Được rồi, và khi tôi tuần tự hóa biểu thức, và Deserialised trên máy chủ, làm thế nào để tôi thực hiện nó chống lại IQueryable của tôi mà tôi có từ lớp DL của tôi? –

+0

Jochen: YourIQueryable.Provider.CreateQuery (receivedExpression) .ToList() –

+0

@ JochenKühner Xin lỗi vì sự chậm trễ. Tôi đã cập nhật bài đăng của mình để trả lời nhận xét của bạn. –

Các vấn đề liên quan