C# 组合来自另外两个表达式的表达式,每个表达式使用不同的属性

2023-12-26

Context

  • 三类:MetaParticipant, MetaMovie and MetaPerson
  • A MetaParticipant有一个MetaMovie和一个MetaPerson

为了解决问题,我创建了一个IsEqual所有三个中的静态方法 https://stackoverflow.com/questions/75393985/c-sharp-using-equals-in-where-clause-doesnt-translate-to-proper-query.

对于独立的人来说MetaMovie and MetaPerson, 我用了 (MetaPerson除了其类之外具有相同的特征):

public static System.Linq.Expressions.Expression<Func<MetaMovie, bool>> IsEqual(MetaMovie other)
{
    if (other.Id > 0) return m => other.Id == m.Id; // Using '> 0' so it skips the new ones in change tracker to the next identifier

    return m => other.MetaSource == m.MetaSource && other.ExternalId == m.ExternalId;
}

所以,我想写下MetaParticipant.IsEqual方法,但无法弄清楚如何。

该方法将收到一个MetaParticipant可以使用它的MetaMovie and MetaPerson给其他人打电话。

Issue

这里是MetaParticipant.Equals that IsEqual应“替换”:

public override bool Equals(object obj)
{
    if (obj == null) return false;
    if (base.Equals(obj)) return true;
    if (obj is not MetaParticipant other) return false;

    return Movie.Equals(other.Movie) && Person.Equals(other.Person) && JobTitle == other.JobTitle;
}

我要做的是什么IsEqual:

public static Expression<Func<MetaParticipant, bool>> IsEqual(MetaParticipant other)
{
    //var own = new Expression<Func<MetaParticipant, bool>() { return x => x.JobTitle == other.JobTitle; };

    var mm = MetaMovie.IsEqual(other.Movie);
    var mp = MetaPerson.IsEqual(other.Person);

    var body = Expression.AndAlso(
        Expression.Invoke(mm, Expression.Parameter(other.Movie.GetType(), "mm")),
        Expression.Invoke(mp, Expression.Parameter(other.Person.GetType(), "mp"))
        );
    //body = Expression.AndAlso(body, );

    var lambda = Expression.Lambda<Func<MetaParticipant, bool>>(body, Expression.Parameter(typeof(MetaParticipant)));
    return lambda;
    //return m => Expression.Invoke(mm, Expression.Variable(m.Movie.GetType())) && m.JobTitle == other.JobTitle;
}

抱歉,我保留了一些垃圾,所以你可以看到我所做的一些尝试。


在@NetMage和另一个问题中其他人的帮助下(但不幸的是他删除了他的答案),我弄清楚了如何做到这一点。

使用.NET 7.0,我可以使用该类ReplacingExpressionVisitor更改两个表达式以使用相应的属性。

public static Expression<Func<MetaParticipant, bool>> IsEqual(MetaParticipant other)
{
    var participantParam = Expression.Parameter(typeof(MetaParticipant), "m");

    var movieExpression = MetaMovie.IsEqual(other.Movie);
    var movieParamReplacer = new ReplacingExpressionVisitor(new[] { movieExpression.Parameters[0] }, new[] { Expression.Property(participantParam, nameof(Movie)) });

    var personExpression = MetaPerson.IsEqual(other.Person);
    var personParamReplacer = new ReplacingExpressionVisitor(new[] { personExpression.Parameters[0] }, new[] { Expression.Property(participantParam, nameof(Person)) });

    var jobTitleProperty = Expression.Property(participantParam, nameof(JobTitle));
    var otherJobTitle = Expression.Constant(other.JobTitle);
    var jobTitle = Expression.Equal(jobTitleProperty, otherJobTitle);

    var newBody = Expression.AndAlso(movieParamReplacer.Visit(movieExpression.Body), personParamReplacer.Visit(personExpression.Body));
    newBody = Expression.AndAlso(newBody, jobTitle);

    var lambda = Expression.Lambda<Func<MetaParticipant, bool>>(newBody, participantParam);
    return lambda;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 组合来自另外两个表达式的表达式,每个表达式使用不同的属性 的相关文章

随机推荐