2016-11-01 5 views
0

私は、UserInterface、BusinessLogic、Service(WCF)、DataAccess(EF6)の4層のアーキテクチャプロジェクトを持っています。私はEFを使って評価するために私のデータアクセス層に渡すことができる表現を受け入れる私のサービスでメソッドを公開しました。ただし、式がシリアライズ可能ではないため、これは機能しません。WCFがシリアライズ可能ではないため、式ツリーは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); 
      } 
     } 

私はこれをやっている方法に代わるものはありますか?式と関数が直列化できない理由はありますか?

+1

あなたはこのライブラリを使用しようとすることができます:https://github.com/esskar/Serialize.LinqをAlreayはここに答え – Evk

+1

: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

関連する問題