2016-11-01 36 views
0

我有一個4層架構的項目,即UserInterface,BusinessLogic,服務(WCF)和數據訪問(EF6)層。我在我的服務中公開了接受表達式的方法,我可以將它傳遞給我的數據訪問層,以便使用EF進行評估。但是,這不起作用,因爲表達式不可序列化。如何使用Expression Tree無法使用WCF工作,因爲它們不可序列化?

在我的客戶端,我希望能夠構建可查詢的表達式以發送到服務器端並返回正確的投影。

服務器端:

public virtual IEnumerable<Person> Get(Expression<Func<Person, bool>> expression) 
     { 
      using (var ctx = MyContext()) 
      { 
       IQueryable<PersonDto> col = ctx.DbContext.People.Where(expression); 
       // 
       return col.ToList(); 
      } 
     } 

客戶端:

public IEnumberable<PersonDto> GetFromService(Expression<Func<PersonDto, bool>> expression) 
     { 
      using (MyService client = new MyService()) 
      { 
       return client.Get(expression); 
      } 
     } 

是否有我這樣做的方式替代?那麼爲什麼表達式和funcs不可序列化是有原因的嗎?

+1

您可以嘗試使用這個庫:https://github.com/esskar/Serialize.Linq – Evk

+1

Alreay回答這裏:https://stackoverflow.com/questions/567316/can-you-pass-funct-bool-through-a-wcf-service –

+0

是否有序列化表達式樹與字符串標準的原因?即將字符串標準傳遞給服務器,然後服務器構建表達式樹。對錶達式樹進行序列化會增加複雜性/開銷,使調試/故障排除變得困難。 –

回答

3

您可以使用Remote.Linq。該項目目前在GitHub上託管,但似乎沒有文檔。但是您可以使用CodePlex中的old one

最簡單的方式來實現這一目標(從舊的文件複製的代碼)

// create linq expression 
System.Linq.Expressions.Expression<Func<Order, bool>> linqExpression = 
    order => order.Items.Where(i => i.ProductId == prodId).Sum(i => i.Quantity) > 1; 

// transform linq expression into serializable expression tree 
Remote.Linq.Expressions.LambdaExpression serializableExpression = 
    linqExpression.ToRemoteLinqExpression(); 

// transform serializable expression tree back into linq expression 
System.Linq.Expressions.Expression<Func<Order, bool>> recreatedLinqExpression = 
    serializableExpression.ToLinqExpression<Order, bool>(); 
3

爲您的特定情況下,它會更簡單(也許更安全),只是通過WHERE條件爲一個字符串,在服務器上使用動態LINQ。

using System.Linq.Dynamic; 

public virtual IEnumerable<Person> Get(string condition) 
    { 
     using (var ctx = MyContext()) 
     { 
      return = ctx.DbContext.People.Where(condition).ToList(); 
     } 
    } 

此處瞭解詳情:Using the LINQ Dynamic Query Library

相關問題