Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.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# 将字符串转换为lambda表达式以传递给LINQ Select_C#_Linq Expressions - Fatal编程技术网

C# 将字符串转换为lambda表达式以传递给LINQ Select

C# 将字符串转换为lambda表达式以传递给LINQ Select,c#,linq-expressions,C#,Linq Expressions,这是我要转换为lambda表达式的字符串 "o => new { Division = o.Division, Department = o.Department }" 实际上,我想创建一个匿名类型的select lambda表达式 我可以得到这个表达式: o => new SystemViewModel { Division = o.Division, Department = o.Department } 但是我想要这个表达 o => new { Division =

这是我要转换为lambda表达式的字符串

"o => new { Division = o.Division, Department = o.Department }"
实际上,我想创建一个匿名类型的select lambda表达式

我可以得到这个表达式:

o => new SystemViewModel { Division = o.Division, Department = o.Department } 
但是我想要这个表达

o => new { Division = o.Division, Department = o.Department}
这是密码

var dte = ctx.Database.SqlQuery<SystemViewModel>("select distinct Division,Department from TestReportView").ToList();"

var result2 = dte.Select(CreateNewStatement(string.Join(",", "Division,Department"))).ToList();

Func<SystemViewModel, SystemViewModel> CreateNewStatement(string fields)
{
    // input parameter "o"
    var xParameter = Expression.Parameter(typeof(SystemViewModel), "o");

    // new statement "new Data()"
    var xNew = Expression.New(typeof(SystemViewModel));

    // create initializers
    var bindings = fields.Split(',').Select(o => o.Trim())
        .Select(o => {

    // property "Field1"
    var mi = typeof(SystemViewModel).GetProperty(o);

    // original value "o.Field1"
    var xOriginal = Expression.Property(xParameter, mi);

    // set value "Field1 = o.Field1"
    return Expression.Bind(mi, xOriginal);
        }
    );

    // initialization "new Data { Field1 = o.Field1, Field2 = o.Field2 }"
    var xInit = Expression.MemberInit(xNew, bindings);

    // expression "o => new Data { Field1 = o.Field1, Field2 = o.Field2 }"
    Type anonType = new { Name = "abc", Num = 123 }.GetType();
    var lambda = Expression.Lambda<Func<SystemViewModel, SystemViewModel>>(xInit, xParameter);
    var e = lambda.Body.ToString();
    //LambdaExpression.
    // compile to Func<Data, Data>
    return lambda.Compile();
}
var dte=ctx.Database.SqlQuery(“从TestReportView中选择不同的部门”).ToList();"
var result2=dte.Select(CreateNewStatement(string.Join(“,”,“Division,Department”)).ToList();
Func CreateNewStatement(字符串字段)
{
//输入参数“o”
var xParameter=Expression.Parameter(typeof(SystemViewModel),“o”);
//新语句“newdata()”
var xNew=Expression.New(typeof(SystemViewModel));
//创建初始值设定项
var bindings=fields.Split(',')。选择(o=>o.Trim())
.选择(o=>{
//属性“字段1”
var mi=typeof(SystemViewModel).GetProperty(o);
//原始值“o.Field1”
var xOriginal=Expression.Property(xParameter,mi);
//设置值“Field1=o.Field1”
返回表达式.Bind(mi,xOriginal);
}
);
//初始化“新数据{Field1=o.Field1,Field2=o.Field2}”
var xInit=Expression.MemberInit(xNew,bindings);
//表达式“o=>新数据{Field1=o.Field1,Field2=o.Field2}”
键入anonType=new{Name=“abc”,Num=123}.GetType();
var lambda=表达式.lambda(xInit,xParameter);
var e=lambda.Body.ToString();
//LambdaExpression。
//编译成Func
返回lambda.Compile();
}

这将返回一个
SystemViewModel
列表,但我需要一个匿名类型列表,其中只有两个动态字段Division和Department(
SystemViewModel
包含许多其他字段)。

如您所知,您不能简单地使用
var xNew=Expression.New(typeof(object));
而不是
var xNew=Expression.New(typeof(SystemViewModel));
引发异常时:

System.ArgumentException:“”分区“”不是“System.Object”类型的成员

因此,对我来说,解决方案是自己创建匿名类型。要在运行时创建类型,您需要创建一个带有动态模块的动态程序集。您还必须考虑缓存这些类型,否则将出现内存不足异常

声明惰性模块生成器

首先,我们将声明一个
Lazy
static
ModuleBuilder
,它将创建一个作为单例的动态模块:

private static Lazy<ModuleBuilder> ModuleBuilder = new Lazy<ModuleBuilder>(() =>
    AssemblyBuilder
        .DefineDynamicAssembly(new AssemblyName("AnonymousTypesAssembly"), AssemblyBuilderAccess.Run)
        .DefineDynamicModule("AnonymousTypesModule"));
用法

private static Type CreateAnonymousType(IEnumerable<PropertyInfo> propertyInfos)
{
    var moduleBuilder = ModuleBuilder.Value;
    var typeName = Guid.NewGuid().ToString(); // Give the new type a random name
    var typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Serializable);

    foreach (var propertyInfo in propertyInfos)
        typeBuilder.DefineField(propertyInfo.Name, propertyInfo.PropertyType, FieldAttributes.Public);

    return typeBuilder.CreateType();
}
var result2 = dte.Select(GetOrCreateNewStatementFor<SystemViewModel>(new HashSet<string> { "Division", "Department" })).ToList();
var result2=dte.Select(GetOrCreateNewStatementFor(newhashset{“Division”,“Department”})).ToList();

您能解释一下您试图解决的问题吗?您在这里描述的是针对您的问题提出的解决方案。请添加用于创建第一个表达式的代码。这可能有助于解决您的问题。可能与“我想要获取动态选择表达式”的重复项,但属于类似“动态”的匿名类型
private static ConcurrentDictionary<string, object> StatementFuncCache = new ConcurrentDictionary<string, object>();

public static Func<TOriginal, object> GetOrCreateNewStatementFor<TOriginal>(ISet<string> fields)
{
    var key = $"{typeof(TOriginal).Name} {string.Join(",", fields.OrderBy(x => x))}";
    var func = StatementFuncCache.GetOrAdd(key, _ => CreateNewStatementFor<TOriginal>(fields));
    return (Func<TOriginal, object>)func;
}
var result2 = dte.Select(GetOrCreateNewStatementFor<SystemViewModel>(new HashSet<string> { "Division", "Department" })).ToList();