2016-08-24 4 views
3

コンテキストを設定して[OK]を、私は私が働いてすべてを取得するために管理している式でのコレクションから、ネストされたプロパティへのアクセス

public class HomeTableInvoice { 
    public int Sys_InvoiceID { get; set; } 
    public bool Turnover { get; set; } 
    public int FK_StatusID { get; set; } 
    public string InvoiceNumber { get; set; } 
    public DateTime InvoiceDate { get; set; } 
    public string DocType { get; set; } 

    public ICollection<InvoiceCustomFields> InvoiceCustomFields { get; set; } 
} 

このクラスを使用して式ツリーを使用して、動的LINQの検索句を構築しています少しと私が使用するパラメータがHomeTableInvoiceであると私はfilter.SysNameは私がフィルタリングしたいフィールドであることを

var parameter = Expression.Parameter(typeof(HomeTableInvoice), "invoice"); 
prop = Expression.Property(param, filter.SysName); 

を使用して表現するためのプロパティの取得することができます。

ICollectionの式を一番下に作成しようとすると問題が発生します。クラスInvoiceCustomFieldsは私が例えば照会すると条件が

where InvoiceNumber == 34 AndAlso (Invoice.InvoiceCustomField.FK_CustomFieldHeader == "Test" && Invoice.InvoiceCustomField.FK_CustomFieldHeader.Value == 42) 

のように見えることができますので、私は

を使用して試したFkCustomFieldHeaderと値の文字列の文字列にアクセスしようとしている

public class InvoiceCustomFields : CustomFieldsBase { 
     public int? FK_SysInvoiceID { get; set; }  
     public string FK_CustomFieldHeader { get; set; }  
     public string Value { get; set; }  
    } 

が含まれています

prop = Expression.PropertyOrField(Expression.PropertyOrField(param, "InvoiceCustomFields"), "FK_CustomFieldHeader"); 

が、それは、このエラーがスローされます

FK_CustomFieldHeader' is not a member of type 'System.Collections.Generic.ICollection`1[APData.Audit.Entityframework.Entities.InvoiceCustomFields]' 

任意のヘルプは、多くのイワンによって答えを試みた後、私はエラー

No generic method 'Any' on type 'System.Linq.Enumerable' is compatible with the supplied type arguments and arguments 

を取得

--Edit--

を高く評価している私は、この

prop = Expression.PropertyOrField(parameter, "InvoiceCustomFields"); 

    var queryableType = typeof(Enumerable); 
    var whereMethod = queryableType.GetMethods() 
     .First(m => { 
     var parameters = m.GetParameters().ToList();        
      return m.Name == "Any" && m.IsGenericMethodDefinition && 
               parameters.Count == 2; 
         }); 

    MethodInfo methoInfo = whereMethod.MakeGenericMethod(prop.Type); 
    var x = Expression.Call(methoInfo, Expression.PropertyOrField(parameter, "InvoiceCustomFields"), whereQuery); 

を試してみましたが、これがスローされます

Expression of type `'System.Collections.Generic.ICollection`1[InvoiceCustomFields]' cannot be used for parameter of type 'System.Linq.IQueryable`1[System.Collections.Generic.ICollection`1[InvoiceCustomFields]]' of method 'Boolean Any[ICollection`1](System.Linq.IQueryable`1[System.Collections.Generic.ICollection`1[InvoiceCustomFields]], System.Linq.Expressions.Expression`1[System.Func`2[System.Collections.Generic.ICollection`1[.InvoiceCustomFields],System.Boolean]])` 

答えて

2

動的でないかどうかを見てみましょう。以下は:

Expression<Func<HomeTableInvoice, bool>> predicate = invoice => 
    invoice.InvoiceCustomField.FK_CustomFieldHeader == "Test" && 
    invoice.InvoiceCustomField.Value == "42"; 

は有効な式ではありません。あなたが実際に行うに必要なもの

は次のようなものです:

Expression<Func<HomeTableInvoice, bool>> predicate = invoice => 
    invoice.InvoiceCustomFields.Any(field => 
     field.InvoiceCustomField.FK_CustomFieldHeader == "Test" && 
     field.InvoiceCustomField.Value == "42"); 

そして、ここであなたが動的にそれを構築する(あなたはあなたの変数をハードコードされた部品を交換するニーズのためにそれを調整することを願って)ことができる方法です。

var parameter = Expression.Parameter(typeof(HomeTableInvoice), "invoice"); 

var fieldParameter = Expression.Parameter(typeof(InvoiceCustomFields), "field"); 
var anyPredicate = Expression.Lambda(
    Expression.AndAlso(
     Expression.Equal(
      Expression.PropertyOrField(fieldParameter, "FK_CustomFieldHeader"), 
      Expression.Constant("Test")), 
     Expression.Equal(
      Expression.PropertyOrField(fieldParameter, "Value"), 
      Expression.Constant("42"))), 
    fieldParameter); 
var fieldCondition = Expression.Call(
    typeof(Enumerable), "Any", new[] { fieldParameter.Type }, 
    Expression.PropertyOrField(parameter, "InvoiceCustomFields"), anyPredicate); 

// You can use the fieldCondition in your combinator, 
// the following is just to complete the example 
var predicate = Expression.Lambda<Func<HomeTableInvoice, bool>>(fieldCondition, parameter); 

// Test 
var input = new List<HomeTableInvoice> 
{ 
    new HomeTableInvoice 
    { 
     InvoiceNumber = "1", 
     InvoiceCustomFields = new List<InvoiceCustomFields> 
     { 
      new InvoiceCustomFields { FK_CustomFieldHeader = "Test", Value = "42" } 
     } 
    }, 
}.AsQueryable(); 
var output = input.Where(predicate).ToList(); 
+0

エラーが発生しました型 'System.Linq.Enumerable'の汎用メソッド 'Any'は、指定された型引数および引数と互換性がありません。 –

+0

私はそれをテストしたのでそれは奇妙です、問題なく動いています(最後にテストコードで更新された答えを見てください)。 –

+0

私の更新答えを見てください:)助けてくれてありがとうございました –

関連する問題