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# 组合来自另外两个表达式的表达式,每个表达式使用不同的属性 的相关文章

  • 如何在MVVM中管理多个窗口

    我知道有几个与此类似的问题 但我还没有找到明确的答案 我正在尝试深入研究 MVVM 并尽可能保持纯粹 但不确定如何在坚持模式的同时启动 关闭窗口 我最初的想法是向 ViewModel 发送数据绑定命令 触发代码来启动一个新视图 然后通过 X
  • 如何验证文件名称在 Windows 中是否有效?

    是否有一个 Windows API 函数可以将字符串值传递给该函数 该函数将返回一个指示文件名是否有效的值 我需要验证文件名是否有效 并且我正在寻找一种简单的方法来完成此操作 而无需重新发明轮子 我正在直接使用 C 但针对的是 Win32
  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • pthread_cond_timedwait() 和 pthread_cond_broadcast() 解释

    因此 我在堆栈溢出和其他资源上进行了大量搜索 但我无法理解有关上述函数的一些内容 具体来说 1 当pthread cond timedwait 因为定时器值用完而返回时 它如何自动重新获取互斥锁 互斥锁可能被锁定在其他地方 例如 在生产者
  • 从父类调用子类方法

    a doStuff 方法是否可以在不编辑 A 类的情况下打印 B did stuff 如果是这样 我该怎么做 class Program static void Main string args A a new A B b new B a
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • 将布尔参数传递给 SQL Server 存储过程

    我早些时候问过这个问题 我以为我找到了问题所在 但我没有 我在将布尔参数传递给存储过程时遇到问题 这是我的 C 代码 public bool upload false protected void showDate object sende
  • 指针问题(仅在发布版本中)

    不确定如何描述这一点 但我在这里 由于某种原因 当尝试创建我的游戏的发布版本进行测试时 它的敌人创建方面不起作用 Enemies e level1 3 e level1 0 Enemies sdlLib 500 2 3 128 250 32
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • Web API - 访问 DbContext 类中的 HttpContext

    在我的 C Web API 应用程序中 我添加了CreatedDate and CreatedBy所有表中的列 现在 每当在任何表中添加新记录时 我想填充这些列 为此目的我已经覆盖SaveChanges and SaveChangesAsy
  • 使用 System.Text.Json 即时格式化 JSON 流

    我有一个未缩进的 Json 字符串 例如 hash 123 id 456 我想缩进字符串并将其序列化为 JSON 文件 天真地 我可以使用缩进字符串Newtonsoft如下 using Newtonsoft Json Linq JToken
  • C# 中的递归自定义配置

    我正在尝试创建一个遵循以下递归结构的自定义配置部分
  • 在数据库中搜索时忽略空文本框

    此代码能够搜索数据并将其加载到DataGridView基于搜索表单文本框中提供的值 如果我将任何文本框留空 则不会有搜索结果 因为 SQL 查询是用 AND 组合的 如何在搜索 从 SQL 查询或 C 代码 时忽略空文本框 private
  • 从路径中获取文件夹名称

    我有一些路c server folderName1 another name something another folder 我如何从那里提取最后一个文件夹名称 我尝试了几件事 但没有成功 我只是不想寻找最后的 然后就去休息了 Thank
  • 控制到达非 void 函数末尾 -wreturn-type

    这是查找四个数字中的最大值的代码 include
  • 如何让Gtk+窗口背景透明?

    我想让 Gtk 窗口的背景透明 以便只有窗口中的小部件可见 我找到了一些教程 http mikehearn wordpress com 2006 03 26 gtk windows with alpha channels https web
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • x86 上未对齐的指针

    有人可以提供一个示例 将指针从一种类型转换为另一种类型由于未对齐而失败吗 在评论中这个答案 https stackoverflow com questions 544928 reading integer size bytes from a
  • mysql-connector-c++ - “get_driver_instance”不是“sql::mysql”的成员

    我是 C 的初学者 我认为学习的唯一方法就是接触一些代码 我正在尝试构建一个连接到 mysql 数据库的程序 我在 Linux 上使用 g 没有想法 我运行 make 这是我的错误 hello cpp 38 error get driver

随机推荐