当前位置: 首页 > 编程语言 > C#

如何在不使用.Compile()的情况下从MemberExpression获取属性值?分享

时间:2023-04-11 10:42:03 C#

不用.Compile()如何获取MemberExpression的属性值?我在不使用.Compile()的情况下尝试从表达式树中获取对象的值时遇到问题。对象很简单。varuserModel=newUserModel{Email="John@Doe.com"};给我问题的方法看起来像这样。privatevoidVisitMemberAccess(MemberExpressionexpression,MemberExpressionleft){varkey=left!=null?left.Member.Name:表达式.Member.Name;if(expression.Expression.NodeType.ToString()=="Parameter"){//添加字符串键_strings.Add(string.Format("[{0}]",key));}else{//添加字符串参数_strings.Add(string.Format("@{0}",key));//潜在的NullReferenceExceptionvarval=(expression.MemberasFieldInfo).GetValue((expression.ExpressionasConstantExpression).Value);//添加参数值Parameters.Add("@"+key,val);}}我正在运行的测试非常简单[测试]//通过publicvoidShouldVisitExpressionByGuidObject(){//Setupvarid=newGuid("CCAF57D9-88A4-4DCD-87C7-DB875E0D4E66");conststringexpectedString="[Id]=@Id";varexpectedParameters=newDictionary{{"@Id",id}};//执行varactualExpression=TestExpression(u=>u.Id==id);varactualParameters=actualExpression.Parameters;var实际字符串=actualExpression.WhereExpression;//测试Assert.AreEqual(expectedString,actualString);CollectionAssert.AreEquivalent(expectedParameters,actualParameters);}[测试]//失败[System.NullReferenceException:对象引用未设置为对象的实例。]publicvoidShouldVisitExpressionByStringObject(){//设置varexpectedUser=newUserModel{Email="john@doe.com"};conststringexpectedString="[Email]=@Email";varexpectedParameters=newDictionary{{"@Email",expectedUser.Email}};//执行varactualExpression=TestExpression(u=>u.Email==expectedUser.Email);varactualParameters=actualExpression.Parameters;varactualString=actualExpression.WhereExpression;//断言Assert.AreEqual(expectedString,actualString);CollectionAssert.AreEquivalent(expectedParameters,actualParameters);}我应该注意改变varval=(expression.MemberasFieldInfo).GetValue((expression.ExpressionasConstantExpression).ValUE);到varval=Expression.Lambda(expression).Compile().DynamicInvoke().ToString();将允许测试通过,但此代码需要在iOS上运行,因此.Compile()不能使用TLDR;只有您可以在不使用Emit或Compile的情况下使用反射在问题中,正在为FieldInfo获取值,而不是为PropertyInfo获取值。确保你能两者兼得。if((expression.MemberasPropertyInfo)!=null){//从PROPERTY获取值}elseif((expression.MemberasFieldInfo)!=null){//从FIELD获取值}else{throw新的InvalidMemberException();冗长的版本所以评论给我指明了正确的方向。在获得PropertyInfo后我有点挣扎,但最终,这就是我想出的。privatevoidVisitMemberAccess(MemberExpressionexpression,MemberExpressionleft){//为了保留键/值对之间的大小写,我们总是希望使用表达式的左侧。//因此,如果left为null,则表达式实际上是left。//这样做可以确保我们的`key`在参数名称和数据库字段之间匹配varkey=left!=null?left.Member.Name:表达式.Member.Name;//如果NodeType是一个`Parameter`,我们希望将键作为数据库字段名称添加到我们的字符串集合中//否则,我们希望将键作为数据库参数添加到我们的字符串集合中if(expression.Expression.NodeType.ToString()=="Parameter"){_strings.Add(string.Format("[{0}]",key));}else{_strings.Add(string.Format("@{0}",key));//如果键被添加为数据库参数,那么我们还必须将参数键/值对添加到集合中//因为我们处理的模型对象应该只包含Properties或Fields,//应该只有两个选项。PropertyInfo或FieldInfo...让我们相应地提取VALUEvarvalue=newobject();if((expression.MemberasPropertyInfo)!=null){varexp=(MemberExpression)expression.Expression;varconstant=(ConstantExpression)exp.Expression;varfieldInfoValue=((FieldInfo)exp.Member).GetValue(constant.Value);value=((PropertyInfo)expression.Member).GetValue(fieldInfoValue,null);}elseif((expression.MemberasFieldInfo)!=null){varfieldInfo=expression.MemberasFieldInfo;varconstantExpression=expression.ExpressionasConstantExpression;if(fieldInfo!=null&constantExpression!=null){value=fieldInfo.GetValue(constantExpression.Value);}}else{抛出新的InvalidMemberException();}//添加参数键/值对。Parameters.Add("@"+key,value);本质上,如果Member.NodeType是一个参数,那么我将它用作SQL字段[FieldName]否则,我将它用作SQL参数@FieldName...向后我知道。如果Member.NodeType不是参数,那么我会检查它是模型字段还是模型属性。从那里,我获得了适当的值并将键/值对添加到字典中以用作SQL参数。最终结果是我构建了一个看起来像SELECT*FROMTableNameWHERE[FieldName]=@FieldName的字符串,然后传递参数varparameters=newDictionaryParameters;parameters.Add("@FieldName","字段的值");以上就是C#学习教程:HowtogetattributevaluesfromMemberExpressionwithout.Compile()?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:

最新推荐
猜你喜欢