0

所以我有一种情况,我需要根据包含的值动态更新对象的属性。在下面的情况下,如果条件为真,我需要用不同的字符串替换当前值的前两个字符来更新值。

PersonDetail.EvaluateConditionalRule("ID", 
                    "((ID.Length > Convert.ToInt32(@0) ) AND ID.Substring(Convert.ToInt32(@1), Convert.ToInt32(@2)) == @3 )",
                     new[] { "1", "0", "2", "SS" }, " ID = (@0  + ID.Substring(Convert.ToInt32(@1))) " , new[] { "98", "2" });


   public static void EvaluateConditionalRule(this PersonDetail  Detail, String PropertyToEvaluate,
            String ConditionalExpression, String[] parameters, String IfTrueExpression,String[] IfTrueExpreassionparameters  )
          {
               var property =  Detail.GetType().GetProperties().Where(x => x.Name == PropertyToEvaluate).FirstOrDefault();
               if (property == null)
                    throw new InvalidDataException(String.Format("Please specify a valid {0} property name for the evaluation.",  Detail.GetType()));
               //put together the condition like so 

               if (new[] {  Detail }.AsQueryable().Where(ConditionalExpression, parameters).Count() > 0 && IfTrueExpression != null)
               {
                    var result = new[] {  Detail }.AsQueryable().Select(IfTrueExpression, IfTrueExpreassionparameters);

                  //Stuck Here as result does not contain expected value 

                    property.SetValue( Detail,result , null);
               }
          }

基本上我想要的是,能够执行提供给它的表达式,而且我认为我没有正确评估子字符串替换表达式的格式。我想从上面是这样的

ID = "98"+  ID.Substring(2);

任何帮助将不胜感激。谢谢

4

2 回答 2

0

不确定您所说的“动态”到底是什么意思,但我认为使用 lambdas 的方法不适合您:

static void Main(string[] args) {
        User user = new User { ID = 5, Name = "Test" };
        SetNewValue(user, u => u.Name, s => s.StartsWith("T"), s => s + "123");
    }

    static void SetNewValue<TObject, TProperty>(TObject obj, Func<TObject, TProperty> propertyGetter, Func<TProperty, bool> condition, Func<TProperty, TProperty> modifier) {
        TProperty property = propertyGetter(obj);
        if (condition(property)) {
            TProperty newValue = modifier(property);
            //set via reflection
        }
    }

因此,我建议您使用表达式树,它允许您构建您喜欢的任何运行时构造,作为您示例的一部分

var exp = Expression.Call(Expression.Constant("test"), typeof(string).GetMethod("Substring", new[] { typeof(int) }), Expression.Constant(2));            
Console.WriteLine(Expression.Lambda(exp).Compile().DynamicInvoke()); //prints "st"

但是,如果您想使用带有原始 c# 代码的字符串作为表达式,请检查CSharpCodeProvider

于 2013-09-06T23:31:49.883 回答
0

请向我们提供一些信息,说明您为什么需要更新才能保持这种动态。您是否希望用户手动输入条件字符串?

关于您的代码:

您的选择器字符串错误。在 LINQ 动态查询库中有一个特殊的语法。请在示例提供的文档中查找(参见段落表达式语言和数据对象初始化器):http: //msdn.microsoft.com/en-US/vstudio/bb894665.aspx

我写了一个小样本:

var id = new string[] { "SS41231" }.AsQueryable();

// *it* represents the current element
var res = id.Where("it.Length > @0 AND it.Substring(@1, @2) = @3", 1, 0, 2, "SS"); // Save the result, don't throw it away.

if (res.Any())
{
    // Line below in normal LINQ: string newID = res.Select(x => "98" + x.Substring(2)).First();
    string newId = res.Select("@0 + it.Substring(@1)", "98", 2).Cast<string>().First();

    Console.WriteLine(newId);
}

请写一些反馈。

问候。

于 2013-09-07T19:46:10.540 回答