C# 将多个不同类型的lambda表达式组合为一个表达式

C# 将多个不同类型的lambda表达式组合为一个表达式,c#,expression,lambda,C#,Expression,Lambda,我想组合一些分离的lambda表达式,并构建它们的最终表达式 示例类: 类地址{ 公共字符串city{get;set;} 公共字符串国家{get;set;} } 甲级{ 公共int Id{get;set;} 公共广播地址{get;set;} } B类{ 公共int Id{get;set;} public ClassA objectA{get;set;} } 每个类都有一个lambda表达式: Expression classARule=a=> a、 Id>1&&a.address.city==

我想组合一些分离的lambda表达式,并构建它们的最终表达式

示例类:

类地址{
公共字符串city{get;set;}
公共字符串国家{get;set;}
}
甲级{
公共int Id{get;set;}
公共广播地址{get;set;}
}
B类{
公共int Id{get;set;}
public ClassA objectA{get;set;}
}
每个类都有一个lambda表达式:

Expression classARule=a=>
a、 Id>1&&a.address.city==“city1”| | a.address.country==“us”
表达式classBRule=b=>b.Id==100
因为
ClassB
有一个属性
ClassA
,所以可以创建一个同时具有这两个条件的表达式。例如:

//我想在运行时使用classARule和classBRule创建这个预期的对象
表达式应为=b=>
(b.Id==100)&&
(b.objectA.Id>1&&b.objectA.address.city==“city1”| | b.objectA.address.country==“美国”)
如果我想在运行时生成预期的表达式,我应该以某种方式将
classARule
a
参数转换为
b.objectA

问题是我知道如何组合两个表达式,但我不知道如何用其他对象替换
a
参数。在这种情况下,
b.objectA


更新-避免更多混淆 目标是使用
classARule
classBRule
在运行时实现预期的
表达式



您需要编译表达式:

class Address
{
    public string city { get; set; }
    public string country { get; set; }
}

class ObjectA
{
    public int Id { get; set; }
    public Address address { get; set; }
}

class ObjectB
{
    public int Id { get; set; }
    public ObjectA objectA { get; set; }
}


Expression<Func<ObjectB, bool>> expected = b =>
    (b.Id == 100) &&
    (b.objectA.Id > 1 && b.objectA.address.city == "City1" || b.objectA.address.country == "US");

// Compile the Expression
var expectedItems = expected.Compile();

List<ObjectB> objBs = new List<ObjectB>();

var address = new Address();
var objA = new ObjectA();
var objB = new ObjectB();
address.city = "City1";
address.country = "US";
objA.Id = 1;
objB.Id = 100;
objA.address = address;
objB.objectA = objA;
objBs.Add(objB);

address = new Address();
objA = new ObjectA();
objB = new ObjectB();
address.city = "City2";
address.country = "US";
objA.Id = 3;
objB.Id = 100;
objA.address = address;
objB.objectA = objA;
objBs.Add(objB);

// Use expectedItems
var result = objBs.FirstOrDefault(b => expectedItems(b));
类地址
{
公共字符串city{get;set;}
公共字符串国家{get;set;}
}
类对象A
{
公共int Id{get;set;}
公共广播地址{get;set;}
}
类对象B
{
公共int Id{get;set;}
public ObjectA ObjectA{get;set;}
}
表达式应为=b=>
(b.Id==100)&&
(b.objectA.Id>1&&b.objectA.address.city==“City1”| | b.objectA.address.country==“美国”);
//编译表达式
var expectedItems=expected.Compile();
List objBs=新列表();
var address=新地址();
var objA=新对象a();
var objB=new ObjectB();
address.city=“City1”;
address.country=“美国”;
objA.Id=1;
对象Id=100;
objA.address=地址;
objB.objectA=objA;
objBs.Add(objB);
地址=新地址();
objA=新对象a();
objB=新对象b();
address.city=“City2”;
address.country=“美国”;
objA.Id=3;
对象Id=100;
objA.address=地址;
objB.objectA=objA;
objBs.Add(objB);
//使用expectedItems
var result=objBs.FirstOrDefault(b=>expectedItems(b));

幸运的是,我解决了这个问题。 如果其他人遇到这样的问题,这里的最终结果就是他们


公共静态表达式组合(这个表达式expr1,Expression你只是想让你的func接受两个参数而不是一个参数吗?我有点搞不懂你在说什么asking@Jonesopolis不,我希望基于类的每个属性动态组合所有规则。这些规则对我的数据库查询应用了一些限制,例如,因为ObjectB引用了ObjectA I想要在运行时为最终查询添加objectA限制可以在编译时这样做,并将
a
更改为
b.objectA
属性。就像上面的例子。我的问题是在运行时应该如何做?@Jonesopolis我写了很多表达式,但现在我也很困惑:)我认为在这种情况下这是正常的。XD我的问题不是加载项。我没有想要创建的
预期的
表达式。我只是演示了表达式和编译。这段代码可以(与编译一起)工作,您的缺少编译,因此也没有。您要创建的表达式缺少哪部分?是因为我使用了ObjectA(此处未显示-在类定义中)还有ObjectB,而不是ClassA和ClassB?-还是添加了它们。不,我只是重命名了类名,以简化示例并避免更多混淆。
Expression expected
这是我想使用另外两个表达式(A&B规则)创建的示例。我不想手动创建此表达式。
目标是在运行时使用classARule和classBRule实现预期的表达式
Ahhh,很抱歉错误地解释了您试图执行的操作。这将取决于您如何存储/提供每个类的表达式-您是否有一个方法可以检索要加入的表达式?是吗它们是通过委托传递的?最后,您需要构建表达式树,在不同的对象(ClassA、ClassB、ClassC等)之间循环以及要检查的属性来构建单个表达式。但是,单个表达式需要一种对象类型-您当前有两种。这使我认为您必须逐个检查每个表达式。您还应该包括一个解释(代码中的一些注释应该足够了)@Nkosi我在我的代码中添加了一些注释。希望它能帮助您准确理解代码的工作原理。我理解代码。我建议为那些将来来查看您答案的人添加注释,他们可能不理解正在做什么以及为什么。很高兴您找到了解决方案。