2017-03-15 56 views
2

我想擴展我的IQueryable以獲取字段名列表並僅將這些列返回到動態集合中。基本上我想用傳入的字段/列名實現「選擇」。該方法會是這個樣子:動態構建帶.NET字段名的IQueryable Select子句核心

private IQueryable<TEnity> SetSelect(IQueryable<TEntity> query, List<string> fieldnames) 
{ 
    //Build up the Expression here 
    query = query.Select(expressionHere); 
    return query; 
} 

所以,如果我是反對的對象像查詢:

public Class Dog 
{ 
    int Id{get;set;} 
    string Name{get;set;} 
    string Color{get;set;} 
    DateTime Birthdate{get;set;} 
} 

但我只想要得到的名稱和生日,我可以通過調用SetSelect(query, new List<string>{"Name", "Birthdate"});延長的IQueryable

而且將返回:

[{"Fido", 01-01-2017}, {"Spot", 05-04-1972}] 

有任何人做了類似的事情,並可以幫助我建立表達?

感謝您的任何澄清。

注意:這是一個.NET的核心應用

+0

這看起來已經回答[這裏](http://stackoverflow.com/questions/606104/how-to-create-linq -expression-tree-to-select-an-anonymous-type) – danatcofo

+0

我忘了添加一個關鍵點。這是一個.Net核心應用程序。上面引用的答案使用了一些我不知道的類。 – KickinMhl

+0

上一個答案[快捷方式](http://stackoverflow.com/a/28140345/740108)對於同一個問題可能是一個更容易的工作解決方案路徑。 – danatcofo

回答

0

可以生成動態選擇由實體呼叫DynamicSelectGenerator的選擇。

public static Func<T, T> DynamicSelectGenerator<T>(string fields) 
      { 
      // get Properties of the T 
      var fields = typeof(T).GetProperties().Select(propertyInfo => propertyInfo.Name).ToArray(); 

      // input parameter "o" 
      var xParameter = Expression.Parameter(typeof(T), "o"); 

      // new statement "new Data()" 
      var xNew = Expression.New(typeof(T)); 

      // create initializers 
      var bindings = fields.Split(',').Select(o => o.Trim()) 
       .Select(o => 
       { 

        // property "Field1" 
        var mi = typeof(T).GetProperty(o); 

        // original value "o.Field1" 
        var xOriginal = Expression.Property(xParameter, mi); 

        // set value "Field1 = o.Field1" 
        return Expression.Bind(mi, xOriginal); 
       } 
      ); 

      // initialization "new Data { Field1 = o.Field1, Field2 = o.Field2 }" 
      var xInit = Expression.MemberInit(xNew, bindings); 

      // expression "o => new Data { Field1 = o.Field1, Field2 = o.Field2 }" 
      var lambda = Expression.Lambda<Func<T, T>>(xInit, xParameter); 

      // compile to Func<Data, Data> 
      return lambda.Compile(); 
     } 

再舉例來說,這段代碼的使用:

var result = dbContextInstancs.EntityClass.Select(DynamicSelectGenerator<EntityClass>("Name", "Birthdate")); 
+1

您用T參數中的字段的完整列表覆蓋方法的參數「字段」。那麼你如何構建一個有限的列表? – GregJF

+0

@GregJF _limited list_是什麼意思?在我的答案示例中,您可以看到'fields'參數是'(「Name」,「Birthdate」)'......您可以發送更多/更少的字段 –