Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将字符串转换为linq表达式?_C#_Asp.net Mvc 3_Linq_Generics - Fatal编程技术网

C# 如何将字符串转换为linq表达式?

C# 如何将字符串转换为linq表达式?,c#,asp.net-mvc-3,linq,generics,C#,Asp.net Mvc 3,Linq,Generics,类似的: 一个类似的例子: 另一个答案相同的问题: 问这么多类似问题的原因: 这些类似问题的公认答案是不可接受的,因为它们都引用了4年前为旧框架(.net 3.5)编写的库(尽管它是由代码大师Scott Gu编写的),并且只提供了一个链接作为答案 有一种方法可以在不包含整个库的情况下在代码中实现这一点 以下是这种情况下的一些示例代码: public static void getDynamic<T>(int startingId) where T : class {

类似的:

一个类似的例子:

另一个答案相同的问题:

问这么多类似问题的原因:

这些类似问题的公认答案是不可接受的,因为它们都引用了4年前为旧框架(.net 3.5)编写的库(尽管它是由代码大师Scott Gu编写的),并且只提供了一个链接作为答案

有一种方法可以在不包含整个库的情况下在代码中实现这一点

以下是这种情况下的一些示例代码:

    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.STRING;

我还没有尝试过这个,也不确定它是否有效,但您可以使用类似于:


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

下面是一个表达式树尝试。我仍然不知道这是否适用于实体框架,但我认为值得一试

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();  
}

要点是getter只是一个函数,您可以像平常一样使用它。阅读
Func
如下:
int-DoSomething(T实例)

以下是我的测试代码(linqPad)的扩展方法:

结果:


您是否排除了使用简单反射来实现
函数的可能性?@PaulPhillips-反射将生成传入的类T中的属性类型或名称。当连接到实体框架存储库时,类T仅作为类型的引用传入。从存储库返回所有类T的列表(
repo.getList()
)。反射如何帮助在linq表达式中包含来自T类的属性?您的示例使它看起来像是在对对象执行linq,在这种情况下,您可以反射地获取属性的值。但既然你在另一个环境下工作,我不确定它是否会起作用。我发布了我的尝试,这样你就可以检查一下,如果你想在这个问题上悬赏,你应该这么做,说这样或那样的答案会被悬赏是愚蠢的。@Hogan-对不起,我在接下来的2天内不能发布悬赏。如果可以,我会的。也许这是你可以在meta上提出的一个问题。这看起来很有趣,至少可以编译。还有更多的测试要做。我能够在linqPad中实现这一点——这是@Paul的代码——感谢您提供了一些有用的代码和示例。我也能让它工作。我没有改变签名,因为它会干扰更多的linq。我确实有一个问题,我需要做什么才能这样使用
MakeGetter
w=>“text”+MakeGetter(classTypeId)
?类似于
w=>“text”+w.classTypeId
@PaulPhillips-感谢您的编辑和澄清。尽管我在MSDN和网络上阅读了大量文档,但我仍然习惯于委托、函数和表达式树。我很感激。这在您的示例中是有效的,但是,在这里我看不到与linq的集成。参见Paul关于linq集成的回答。我猜,他在类型上的工作是在对象上的工作。。。六个一个。我认为我的会更有表现力,因为没有模板需要。
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))
var getId = MakeGetter<T>(classTypeId);

return w => "text" + getId(w); 
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);
  }
}