我在运行时为给定的成员生成编译的getter方法.现在,我的代码只是假设getter方法的结果是一个字符串(适用于测试).但是,我想用我编写的自定义转换器类来完成这项工作,请参阅下面的"ConverterBase"参考,我已经添加了.
我无法弄清楚如何将转换器类的调用添加到我的表达式树.
public Func<U, string> GetGetter<U>(MemberInfo info)
{
Type t = null;
if (info is PropertyInfo)
{
t = ((PropertyInfo)info).PropertyType;
}
else if (info is FieldInfo)
{
t = ((FieldInfo)info).FieldType;
}
else
{
throw new Exception("Unknown member type");
}
//TODO, replace with ability to specify in custom attribute
ConverterBase typeConverter = new ConverterBase();
ParameterExpression target = Expression.Parameter(typeof(U), "target");
MemberExpression memberAccess = Expression.MakeMemberAccess(target, info);
//TODO here, make the expression call "typeConverter.FieldToString(fieldValue)"
LambdaExpression getter = Expression.Lambda(memberAccess, target);
return (Func<U, string>)getter.Compile();
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找第二个TODO区域的内容(我可以处理第一个:)). …
我正在考虑Expression<Func<>>和 之间的区别Func<>,想知道是否可以将静态方法转换为表达式树,如下所示:
class Program
{
static void Main(string[] args)
{
Func<int, int> t = x => hrm(x);
Func<int, int> t2 = new Func<int, int>(hrm);
// Works as expected:
Expression<Func<int, int>> et = x => hrm(x);
// Brokenness:
Expression<Func<int, int>> et2 = new Func<int, int>(hrm);
}
static int hrm(int x)
{
return x + 9;
}
}
Run Code Online (Sandbox Code Playgroud)
第二个“Func<>”有何特别之处,以至于它无法转换为表达式,而第一个“Func<>”可以转换为表达式?
我需要一种方法来遍历 LINQ-to-SQL 表达式树以提取查询中的表名称。即使只是查询中使用的第一个表可能就足够了。
例子:
var query = from c in Db.Customers select c;
Run Code Online (Sandbox Code Playgroud)
以及理想的函数:
string TableName = ExtractTablesFromQuery(query);
Run Code Online (Sandbox Code Playgroud)
将返回字符串“Customers”
我正在尝试构建一个通用类来处理来自EF的实体.这个类与存储库进行对话,但是这个类创建了发送到存储库的表达式.无论如何,我只是想实现一个虚拟方法,它将作为常见查询的基础.具体来说,它将接受一个an int,它只需要对相关实体的主键执行查询.
我一直在搞砸它,我已经建立了一个可能或可能不起作用的反射.我这样说是因为我得到一条NotSupportedException带有LINQ to Entities的消息,无法识别方法'System.Object GetValue(System.Object,System.Object [])'方法,并且此方法无法转换为商店表达式.所以然后我尝试了另一种方法,它产生了相同的异常,但LINQ表达式错误的节点类型'ArrayIndex'在LINQ to Entities中不受支持.我知道这是因为EF不会像L2S那样解析表达式.
无论如何,我正在跳跃一个有更多经验的人可以指出我正确的方向.我正在用我所做的两次尝试发布整个班级.
public class Provider<T> where T : class {
protected readonly Repository<T> Repository = null;
private readonly string TEntityName = typeof(T).Name;
[Inject]
public Provider(
Repository<T> Repository) {
this.Repository = Repository;
}
public virtual void Add(
T TEntity) {
this.Repository.Insert(TEntity);
}
public virtual T Get(
int PrimaryKey) {
// The LINQ expression node type 'ArrayIndex' is not supported in
// LINQ …Run Code Online (Sandbox Code Playgroud) 我想确定要使用什么......
我需要IEnumerable<TSource>将一个函数传递给将实体成员的值写入文件的函数.这是IEnumerable的样子:
var persons = new[] {
new Person {
RecordID = 0,
PersonFName = "Joe",
PersonMName = "",
PersonLName = "Smith",
PersonZip="75227"
},
new Person {
RecordID = 1,
PersonFName = "Mary",
PersonMName = "Hada",
PersonLName = "Lamb",
PersonZip="75217"
}};
Run Code Online (Sandbox Code Playgroud)
将IEnumerable传递给读取每个实体的函数以便读取每个字段值的最佳方法是什么?
我以为我会用以下东西:
void WriteData<TSource>(Expression<IEnumerable<Person>> expression)
{
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
我无法找到解释如何确定何时应该使用Expression而不仅仅是传递IEnumerable的资源.然后,我如何创建反映的表达式persons?
理想情况下,似乎我会像这样调用WriteData:
WriteData(persons);
Run Code Online (Sandbox Code Playgroud)
我是否朝着正确的方向前进?
我有(例如) a ,Func<int, int>我想像往常一样调用它,除了参数的类型为objectratingr than int。我只知道 Func 的确切类型和运行时的参数,因为 Func 是使用表达式树创建的,现在可以从变量访问dynamic。(简化)代码示例:
using System.Linq.Expressions;
namespace FuncExample
{
class Program
{
static void Main(string[] args)
{
object myFunc = CreateFunc(); // Could return something like
// Func<int, int>, but may return a
// completely different Func<> depending on
// arguments etc.
object result = getFromFunc(5, myFunc);
}
public static object CreateFunc()
{
LambdaExpression expr = Expression.Lambda(
/*
* Create an expression
*/
);
return expr.Compile();
} …Run Code Online (Sandbox Code Playgroud) 我上课了
public class SomeClass
{
public int num { get; set; }
public string str{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我需要构造一个lambda表达式,如:(x => new {new_num = x.num,new_str = x.str})
属性列在一些可枚举对象中(这很重要).让我们说吧List<KeyValuePair<string, string>>
我的代码是:
// Test properties list
var listOfParams = new List<KeyValuePair<string, string>>();
listOfParams.Add(new KeyValuePair<string, string>("new_num","num"));
listOfParams.Add(new KeyValuePair<string, string>("new_str","str"));
// SomeClass as particular test case
var tModelType = typeof(SomeClass);
ParameterExpression pe = Expression.Parameter(tModelType, "m");
NewExpression ne = Expression.New(typeof(object)); //<-- trying to emulate `new object{}`
List<Expression> lInit = new List<Expression>();
PropertyInfo pi; …Run Code Online (Sandbox Code Playgroud) 我在形成动态查询表达式期间处理Nullable类型的scanario.这些表达式将从任何SQL表中获取过滤数据(使用EF与Code First类连接).
我有正常的对象(例如,托运操作几个属性以及Nullable属性).
我的表达形式很顺利,直到我遇到一些Nullable类型.在这些无用之处,我得到了
没有为类型'System.Nullable`1 [System.Single]'和'System.Single'定义二元运算符NotEqual.
为了删除此异常,我正在使用关于在不同线程上发布的转换的所有appraoches.
这些都是生成带有"Convert"字样的表达式(即Convert(someValue)),结果我总是有表达式
t=>(t.Consignment.Id = 45000 && t.Consignment.someProperty>=45 Or t.Consignment.Weight! = Convert(5000)).
Run Code Online (Sandbox Code Playgroud)
当然我需要整个上面的表达式没有"转换".因为这个"转换"不会相应地从表中获取数据.
任何帮助将不胜感激!还应该做什么?我已经知道转换,但是这使得整个表达式无用,因为它不会因为不必要的"转换"而投影记录
添加
Expression NotEqual<T>(Expression PropertyType, ConstantExpression a_Constant, ParameterExpression parameter)
{
if(IsNullableType(Property.Type) &&!IsNullableType(a_Constant.Type))
{
var converted = a_Constant.Type != Property.Type ? (Expression)Expression.Convert(a_Constant, Property.Type): (Expression)a_Constant;
// here above statement returns (Convert(50000)) and all I want (50000), but i tried all combinitions from Expression in order to form this constant as expression, it always throws exception what I mentioned originally.
var body = …Run Code Online (Sandbox Code Playgroud) 我有以下字符串表达式定义对象遍历"eBnum".其中e定义了我的字符串表达式中的根实体
class BTest
{
public int num{get:set;}
}
class Test
{
public int sample {get; set;}
public BTest B {get; set;}
}
static void TestProperty()
{
Test obj = new Test();
obj.sample = 40;
obj.B = new BTest(){ num=5}
Expression propertyExpr = Expression.Property(Expression.Constant(obj),"num");
Console.WriteLine(Expression.Lambda<Func<int>>(propertyExpr).Compile()());
Run Code Online (Sandbox Code Playgroud)
}
在下面的语句Expression.Property(Expression.Constant(obj),"num"); 我能够获得第一级属性"sample"的值,但不能获得第二级属性的值?
我在这里错过了什么吗?我试图基于"num"属性值构建一个二进制表达式.
expression-trees ×10
c# ×9
lambda ×2
reflection ×2
.net-4.0 ×1
dynamic ×1
expression ×1
func ×1
linq ×1
linq-to-sql ×1