簡體   English   中英

如何將字符串轉換為linq表達式?

[英]how to turn a string into a linq expression?

類似: 將字符串轉換為Linq.Expressions或使用字符串作為選擇器?

類似的那個: 將Linq表達式作為字符串傳遞?

另一個問題有相同的答案: 如何從C#中的字符串創建基於動態lambda的Linq表達式?

詢問有這么多類似問題的事情的原因:

在這些類似問題中接受的答案是不可接受的,因為他們都引用了4年前的一個庫(授予它是由代碼大師Scott Gu編寫的)為舊框架(.net 3.5)編寫的,並且除了鏈接作為答案。

有一種方法可以在代碼中執行此操作,而不包括整個庫。

以下是此情況的示例代碼:

    public static void getDynamic<T>(int startingId) where T : class
    {
        string classType = typeof(T).ToString();
        string classTypeId = classType + "Id";
        using (var repo = new Repository<T>())
        {
            Build<T>(
             repo.getList(),
             b => b.classTypeId //doesn't compile, this is the heart of the issue
               //How can a string be used in this fashion to access a property in b?
            )
        }
    }

    public void Build<T>(
        List<T> items, 
        Func<T, int> value) where T : class
    {
        var Values = new List<Item>();
        Values = items.Select(f => new Item()
        {
            Id = value(f)
        }).ToList();
    }

    public class Item
    {
     public int Id { get; set; }
    }

請注意,這並不是要將整個字符串轉換為表達式,例如

query = "x => x.id == somevalue";

但反而只是嘗試使用字符串作為訪問

query = x => x.STRING;

這是表達式樹的嘗試。 我仍然不知道這是否適用於Entity框架,但我認為值得一試。

Func<T, int> MakeGetter<T>(string propertyName)
{
    ParameterExpression input = Expression.Parameter(typeof(T));

    var expr = Expression.Property(input, typeof(T).GetProperty(propertyName));

    return Expression.Lambda<Func<T, int>>(expr, input).Compile();  
}

像這樣稱呼它:

Build<T>(repo.getList(), MakeGetter<T>(classTypeId))

如果你可以使用Expression<Func<T,int>>代替一個Func ,那么只需刪除對Compile的調用(並更改MakeGetter的簽名)。


編輯 :在評論中,TravisJ詢問他如何使用它: w => "text" + w.classTypeId

有幾種方法可以做到這一點,但為了便於閱讀,我建議首先引入一個局部變量,如下所示:

var getId = MakeGetter<T>(classTypeId);

return w => "text" + getId(w); 

重點是吸氣劑只是一個功能,你可以像往常一樣使用它。 像這樣讀取Func<T,int>int DoSomething(T instance)

這是我的測試代碼(linqPad)的擴展方法:

class test
{
   public string sam { get; set; }
   public string notsam {get; set; }
}

void Main()
{
   var z = new test { sam = "sam", notsam = "alex" };

   z.Dump();

   z.GetPropertyByString("notsam").Dump();

   z.SetPropertyByString("sam","john");

   z.Dump();
}

static class Nice
{
  public static void  SetPropertyByString(this object x, string p,object value) 
  {
     x.GetType().GetProperty(p).SetValue(x,value,null);
  }

  public static object GetPropertyByString(this object x,string p)
  {
     return x.GetType().GetProperty(p).GetValue(x,null);
  }
}

結果:

結果

我沒有試過這個,也不確定它是否可行,但是你可以使用類似的東西:

b => b.GetType().GetProperty(classTypeId).GetValue(b, null);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM