【问题标题】:how to create multiple statements lambda expression from string如何从字符串创建多个语句 lambda 表达式
【发布时间】:2019-03-12 09:48:21
【问题描述】:

我们有一些用户数据,在某个时候,我们想为满足某些条件的用户修改用户数据值。 例如:当用户在线时间>100小时,我们可以给他10个金币奖励。

现在我正在使用以下代码对数据进行调整

<!-- language: c# -->
public void UserBounds(List<userdata> DataList)
{

    DataList.Where(p => p.Onlinetime > 100).Select(x =>
            {
                x.Bound = x.Bound + 10;
                return x;
            }).ToList();

    DataList.Where(p => p.isFirstLogin).Select(x =>
            {
                x.Bound = x.Bound + 1;
                return x;
            }).ToList();
}

那么现在标准要高得多,我想使用字符串表达式来执行这些操作,我将过滤器和奖励放在 List.like sql where 和 update syntax 上。
例如
|----------------------|------------------|
|过滤器   |界   |
|----------------------|------------------|
|在线时间>100   |绑定 = 绑定 + 10 |
|------------------------------------|--------|
| isFirstLogin    |绑定 = 绑定 + 5 |
|------------------------------------|--------|

现在我使用 system.linq.dynamic,它可以使用过滤器字符串作为 where 表达式,但是我如何从边界字符串生成表达式语句。比如

"Bound = Bound + 10",表达式为

    x =>{
          x.Bound = x.Bound + 10;
          return x;
        };

谢谢大家。

【问题讨论】:

    标签: c# dynamic lambda expression statements


    【解决方案1】:

    提醒一下,Linq 用于查询数据,而不是更新数据。查询可以将数据转换为另一种形式。

    void Main()
    {
        var data = new []
        {
            new Data { IsFirstLogin = true , OnlineTime =   0, Bound = 0  }, // bound + 5
            new Data { IsFirstLogin = true , OnlineTime = 101, Bound = 0  }, // bound + 15
            new Data { IsFirstLogin = false, OnlineTime =  50, Bound = 10 }, // bound + 0
            new Data { IsFirstLogin = false, OnlineTime = 200, Bound = 25 }, // bound + 10
        };
    
        var query = data
            .Select(x =>
                {
                    x.Bound += 
                        x.IsFirstLogin && x.OnlineTime > 100 ? 15 :
                        x.IsFirstLogin ? 5 :
                        x.OnlineTime > 100 ? 10 : 0;
                    return x;
                }
            )
            .Dump() // remove this line if not in LinqPad
        ;
    }
    
    public class Data
    {
        public bool IsFirstLogin { get; set; }
        public int OnlineTime { get; set; }
        public int Bound { get; set; }
    }
    

    LinqPad 中的结果:

    替代解决方案,将 2 个未映射的属性添加到类中。

    void Main()
    {
        var data = new []
        {
            new Data { IsFirstLogin = true , OnlineTime =   0, Bound = 0  }, // bound + 5
            new Data { IsFirstLogin = true , OnlineTime = 101, Bound = 0  }, // bound + 15
            new Data { IsFirstLogin = false, OnlineTime =  50, Bound = 10 }, // bound + 0
            new Data { IsFirstLogin = false, OnlineTime = 200, Bound = 25 }, // bound + 10
        };
    
        var query = data
            .Select(x =>
                {
                    x.Bound += x.GetBoundIsFirstLogin + x.GetBoundOnlineTime;
                    return x;
                }
            )
            .Dump() // remove this line if not in LinqPad
        ;
    }
    
    public class Data
    {
        public bool IsFirstLogin { get; set; }
        public int OnlineTime { get; set; }
        public int Bound { get; set; }
    
        [NotMapped]
        public int GetBoundIsFirstLogin => IsFirstLogin ? 5 : 0;
        [NotMapped]
        public int GetBoundOnlineTime => OnlineTime > 100 ? 10 : 0;
    }
    

    【讨论】:

      【解决方案2】:

      谢谢韩。
      1.Linq可以更新列表的item值,像这样

      var datas = data.ToList();
      
      datas.Select(p => {
          p.Bound=p.Bound+100;
          return p;
      }).ToList();
      
      datas.Dump();
      

      LinqPad test

      2.关键不是更新列表数据,在我的数据中,我需要根据很多条件改变数据的结果,所以代码定义的条件不适用,只能生成对应的表达式动态地,然后使用这个表达式来更新数据,关键是把字符串转换成一个lambda表达式。 比如将 "Bound=Bound+10" 转换为表达式

      x=>{x.Bound = x.Bound + 10;
      return x;}
      

      3.我想也许可以使用Expression&lt;Action&lt;data&gt;&gt; or Expression&lt;Action&lt;data,data&gt;&gt;, 但是我还没有找到测试它的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-20
        • 1970-01-01
        • 1970-01-01
        • 2010-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多