C# 如何从不同的域转换Lambda表达式?

C# 如何从不同的域转换Lambda表达式?,c#,lambda,expression,expression-trees,linq-expressions,C#,Lambda,Expression,Expression Trees,Linq Expressions,我正在尝试将Lambda表达式从一个域转换为另一个域。 这是我收到的参数: Expression<Func<Entities.UserRight, bool>> expression 表达式 我应该返回一个类型为的表达式 Expression<Func<UserRight,bool>> 表达式 UserRight和Entities.UserRight都是相同的模型,但属于不同的nugget包 我试着: public Expression&

我正在尝试将Lambda表达式从一个域转换为另一个域。 这是我收到的参数:

Expression<Func<Entities.UserRight, bool>> expression
表达式
我应该返回一个类型为的表达式

Expression<Func<UserRight,bool>> 
表达式
UserRight和Entities.UserRight都是相同的模型,但属于不同的nugget包

我试着:

public Expression<Func<UserRight,bool>> ConvertExpression(Expression<Func<Entities.UserRight, bool>> expression)
    {
        var resultBody = Expression.Convert(expression.Body, typeof(UserRight));
        var result = Expression.Lambda<Func<UserRight, bool>>(resultBody, expression.Parameters);
        return result;
    }
公共表达式ConvertExpression(表达式)
{
var resultBody=Expression.Convert(Expression.Body,typeof(UserRight));
var result=Expression.Lambda(resultBody,Expression.Parameters);
返回结果;
}

但是我收到一个InvalidOperationException错误

假设我们有两个类Address1和Address2,如下所示:

class Address1
{
    public string City { get; set; }
    public string Detail { get; set; }
}

class Address2
{
    public string City { get; set; }
    public string Detail { get; set; }
}
当我们有地址1的表达式时,如下所示:

Expression<Func<Address1, string>> getCityName = ad1 => ad1.City;
Expression<Func<Address1, string>> getCityName = ad1 => ad1.City;

var ad2Parameter = Expression.Parameter(typeof(Address2), "ad2");
var convertor = new ExpressionConvertor(ad2Parameter);
var getCityName2 = (Expression<Func<Address2, string>>)convertor.Visit(getCityName);
var getCityName2Method = getCityName2.Compile();

var addr2 = new Address2()
{
    City = "MyCity",
    Detail = "My Address Detail"
};
var cityName = getCityName2Method(addr2);
Console.WriteLine(cityName); //MyCity
最后我们像这样使用这个类:

Expression<Func<Address1, string>> getCityName = ad1 => ad1.City;
Expression<Func<Address1, string>> getCityName = ad1 => ad1.City;

var ad2Parameter = Expression.Parameter(typeof(Address2), "ad2");
var convertor = new ExpressionConvertor(ad2Parameter);
var getCityName2 = (Expression<Func<Address2, string>>)convertor.Visit(getCityName);
var getCityName2Method = getCityName2.Compile();

var addr2 = new Address2()
{
    City = "MyCity",
    Detail = "My Address Detail"
};
var cityName = getCityName2Method(addr2);
Console.WriteLine(cityName); //MyCity
表达式getCityName=ad1=>ad1.City; var ad2Parameter=表达式参数(typeof(Address2),“ad2”); var转换器=新表达式转换器(AD2参数); var getCityName2=(表达式)convertor.Visit(getCityName); var getCityName2Method=getCityName2.Compile(); var addr2=新地址2() { City=“MyCity”, Detail=“我的地址详细信息” }; var cityName=getCityName2Method(addr2); Console.WriteLine(cityName)//我的城市
最终,您需要将第一个表达式映射到另一个表达式,因为不会进行本机转换。为此,您需要从上到下重写表达式树
ExpressionVisitor
是实现这一点的理想选择,但您不能对此天真,因为它包含
PropertyInfo
/
FieldInfo
/
MethodInfo
标记,您需要将这些标记映射到其他类型;这是可能的,但是……如果您有类型为
UserRight
ur
)和
实体的变量。UserRight
eur
)如何将一个转换为另一个?@NetMage可能使用AutoMapper,为什么?因为如果您不能简单地从
eur
转换为
ur
变量,您不能在表达式树中执行此操作-您需要添加适当的lambda框架来处理转换,就像处理变量一样。考虑将<代码> FUNC<代码>转换为<代码> FUNC -您需要用转换lambda <代码> Ur= > FEUR(U.CurrttoEube)(< /代码>)来包装<代码> Fue<代码>。