动态创建匿名对象利用表达式树动态构建分组条件

Posted yzmn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态创建匿名对象利用表达式树动态构建分组条件相关的知识,希望对你有一定的参考价值。

public Type GetMyType(Dictionary<string, Type> dic)
{

string strDynamicModuleName = "dynamic";
string strDynamicClassName = "<>dynamic";
AppDomain currentDomain = System.AppDomain.CurrentDomain;
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = strDynamicModuleName;

AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);

ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(strDynamicModuleName);

TypeBuilder typeBuilder = moduleBuilder.DefineType(strDynamicClassName, TypeAttributes.Public);

Type[] methodArgs = { typeof(string) };

typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);


ConstructorBuilder constructorBuiler = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(string), typeof(int) });

// typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard);
//typeBuilder.d
//动态创建字段
// FieldBuilder fb = typeBuilder.DefineField(item, typeof(System.String), FieldAttributes.Private);
//ILGenerator ilg = constructorBuiler.GetILGenerator();//生成 Microsoft 中间语言 (MSIL) 指令
//ilg.Emit(OpCodes.Ldarg_0);
//ilg.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
//ilg.Emit(OpCodes.Ldarg_0);
//ilg.Emit(OpCodes.Ldarg_1);

////ilg.Emit(OpCodes.Stfld);
//ilg.Emit(OpCodes.Ret);

int index = 0;
ILGenerator ilg = constructorBuiler.GetILGenerator();
foreach (string item in dic.Keys)
{

//typeBuilder.DefineConstructor(MethodAttributes.Assembly, CallingConventions.VarArgs, new Type[] { typeof(string), typeof(int) });

//动态创建字段
//FieldBuilder fb = typeBuilder.DefineField("_" + item, dic[item], FieldAttributes.Private);

//类型的属性成员由两部分组成,一是私有字段,二是访问私有字段的属性包装器。
//包装器运行时的本质与 Method 一样,即包含 Set_Method 和 Get_Method 两个方法。
//动态创建字段
FieldBuilder fieldBuilder = typeBuilder.DefineField(dic[item].Name + "_" + item, dic[item], FieldAttributes.Public);

//FieldBuilder conFieldBuilder = typeBuilder.DefineField(item.ToLower(), dic[item], FieldAttributes.Public);


index++;
ilg.Emit(OpCodes.Ldarg_0);//向MSIL流发送属性实例
ilg.Emit(OpCodes.Ldarg, index);//将指定索引的参数加到堆栈上。
ilg.Emit(OpCodes.Stfld, fieldBuilder);//装载字段

 

//ilg.Emit(OpCodes.Stfld, fieldBuilder);

PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(item, PropertyAttributes.None, dic[item], null);
//MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
MethodBuilder methodBuilder = typeBuilder.DefineMethod("get_" + item, MethodAttributes.Public, dic[item], null);

ILGenerator ilGenerator = methodBuilder.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldfld, fieldBuilder);//装载属性私有字段
ilGenerator.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(methodBuilder);// 设置获取属性值的方法

methodBuilder = typeBuilder.DefineMethod("set_" + item,
MethodAttributes.Public,
typeof(void), new Type[] { dic[item] });

ilGenerator = methodBuilder.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Stfld, fieldBuilder);
ilGenerator.Emit(OpCodes.Ret);
propertyBuilder.SetSetMethod(methodBuilder);// 设置属性值的方法


}
ilg.Emit(OpCodes.Ret);
Type type = typeBuilder.CreateType();

//Type typeDynamic = moduleBuilder.GetType(strDynamicClassName);
//object objReturn = Activator.CreateInstance(typeDynamic, "Admin", 90);

object objReturn = Activator.CreateInstance(type, "Admin", 90);

return type;

}

public async Task AddDistributionExcelDataAsync(List<IN_PnoDetail> listDetail, string TripCode, string checkedList)
{

//1.组建运单
var tripEntity = new IN_Trip();
tripEntity.InitEntity();
tripEntity.TripCode = TripCode;

var service_trip = Service.GetIQueryable<IN_Trip>();
var service_order = Service.GetIQueryable<IN_Order>();

//await Service.InsertAsync(tripEntity);
List<IN_PnoDetail> newListDetail = new List<IN_PnoDetail>();
List<IN_Order> newListOrder = new List<IN_Order>();
//2.组建入库单和详情
IEnumerable<IGrouping<string, IN_PnoDetail>> groups = null;

listDetail.GroupBy(p =>new{p.SupplierCode });
if (checkedList.Contains("供应商"))
{
var groups1 = listDetail.GroupBy(p => new { p.SupplierCode,p.ProductCode });
}

//var type = typeof(IN_PnoDetail);
//var propertyName = "SupplierCode";
//var param = Expression.Parameter(type, type.Name);
//var body = Expression.Property(param, propertyName);
//var keySelector = Expression.Lambda<Func<IN_PnoDetail, dynamic>>(body, param);
//var k = keySelector.Compile();
//var ty = keySelector.GetType();
//var ty1 = typeof(Func<IN_PnoDetail, string>);
//var m = ty == ty1;
//var groupsd = listDetail.GroupBy(k);

 

 

 

string[] namelist = new string[] { "SupplierCode", "ProductCode" };
Dictionary<string, Type> dic = new Dictionary<string, Type>();
dic.Add("SupplierCode", typeof(string));
dic.Add("ProductCode", typeof(string));

Type type= GetMyType(dic);

var param = Expression.Parameter(typeof(IN_PnoDetail), typeof(IN_PnoDetail).Name);

try
{
List<MemberBinding> newBindings = new List<MemberBinding>();
NewExpression newBody = Expression.New(type);

type.GetProperties().ForEach(aProperty =>
{

MemberInfo newMember = type.GetMember(aProperty.Name)[0];
MemberBinding newMemberBinding = Expression.Bind(newMember, Expression.Property(param, aProperty.Name));
newBindings.Add(newMemberBinding);
});
MemberInitExpression body = null;

body = Expression.MemberInit(newBody, newBindings.ToArray());
var keySelector = Expression.Lambda<Func<IN_PnoDetail, dynamic>>(body, param);
var k = keySelector.Compile();
var groupsd = listDetail.GroupBy(k);
}
catch (Exception e)
{

throw;
}


var q = from a in service_order.AsExpandable()
join b in service_trip.Where(c => c.TripCode == TripCode)
on a.In_TripId equals b.Id into ab
select ab.Count();
int number = q.FirstOrDefault();

if (groups != null)
{
foreach (var item in groups)
{
number = number + 1;
IN_Order inorder = new IN_Order() { In_TripId = tripEntity.Id, InOrderCode = $"{TripCode}_{number}" };
inorder.InitEntity();
inorder.State = "未作业";
newListOrder.Add(inorder);

//await Service.InsertAsync(inorder);
foreach (var itemDetai in item)
{
itemDetai.InitEntity();
itemDetai.OrderId = inorder.Id;
itemDetai.TripId = tripEntity.Id;
itemDetai.State = "未作业";
newListDetail.Add(itemDetai);
}
}
}
else
{
number = number + 1;
IN_Order inorder = new IN_Order() { In_TripId = tripEntity.Id, InOrderCode = $"{TripCode}_{number}" };
inorder.InitEntity();
inorder.State= "未作业";
newListOrder.Add(inorder);

newListDetail = listDetail;
newListDetail.ForEach(a => {
a.InitEntity();
a.OrderId = inorder.Id;
a.TripId = tripEntity.Id;
a.State = "未作业";
a.AlreadyNum = 0;
});
}
//await Service.InsertAsync(newListDetail);

 

var res = await RunTransactionAsync(async () =>
{
await Service.InsertAsync(tripEntity);
await Service.InsertAsync(newListOrder);
await Service.InsertAsync(newListDetail);
});
if (res.Success)
{

}
else
throw new Exception("系统异常", res.ex);

//1.保存所有分配明细
//1.1转换类型

//2.按照条件分组生成入库订单和明细

//3.插入运单和运单明细

//4,插入入库单和入库单明细
}

#endregion

#region 私有成员

#endregion


}

以上是关于动态创建匿名对象利用表达式树动态构建分组条件的主要内容,如果未能解决你的问题,请参考以下文章

构建动态表达式树以过滤集合属性

如何构建具有多个条件的 Lambda 表达式树

基于Expression Lambda表达式树的通用复杂动态查询构建器——《构思篇二》已开源

使用多维数组构建对象以动态创建列

如何创建 LINQ 表达式树以选择匿名类型

动态构建Lambda表达式实现EF动态查询