从表达式函数获取父属性

2024-05-18

假设我有以下课程:

public class Model {
    public AnotherModel InnerModel {
        get;
        set;
    }
}

public class AnotherModel {
    public String Value{
        get;
        set;
    }
}

现在我有以下功能:

public static void Foo<T, U>(Expression<Func<T, U>> func) {
     // Get the property info from func
}

我现在想做的是:

Foo<Model, String>(o => o.InnerModel.Value)

问题来了:

我知道您可以通过执行以下操作从表达式 func 中获取 PropertyInfo:

PropertyInfo propertyInfo = (PropertyInfo)((MemberExpression)func.Body).Member;

这将为我提供 Value 属性的 PropertyInfo。但是,我还想获取有关父属性的信息,即 InnerModel 属性。

到目前为止我所知道的是我可以执行以下操作:

((MemberExpression)func.Body).Expression

获取父属性的信息。但是,似乎不可能从表达式本身提取 PropertyInfo。

有没有某种方法可以实际检索表达式的 PropertyInfo?

编辑: 澄清一下,这可能是一个糟糕的尝试方式,但这里是: 我不能为此使用 EntityFramework,只是为了确保人们理解这一点。

我需要通过 API 与一个数据库进行通信。

该数据库具有如下方式的通常关系: 工作台螺纹 用户ID -> 用户.用户ID

现在将其提取到模型中。按照上面的例子:

class Thread {
    [Reference(USER_USERID)]
    [TableKey(THREAD_USERID)]
    public User user {
        get;set;
    }
}

class User {
     [TableKey(USER_USERID)]
     public int UserId {
         get;set;
     }
}

现在我想对此提出疑问。所以我想“嘿,让我们使用表达式来简化最终用户如何请求东西,是的。”

所以,我们可以做类似 EqualTo(o => o.user.UserId, 1); 的事情

但是,由于 TableKey 属性与引用键不同,我需要首先从数据库中获取 Thread 表中的 userId,然后使用该 Id 开始向 User 表询问该 id 的信息。

也许这澄清了这一切的目的,也可能没有。


正如您已经确定的,表达式的主体是 MemberExpression。我们需要查看 MemberExpression 的两个属性。

第一个是会员属性。这是被调用的 MemberInfo。在您的示例中,这是 Value 属性。我们需要查看的第二个属性是 Expression 属性。这就是调用成员表达式的原因。在您的示例中,这是 {o.InnerModel}。

{o.InnerModel} 是另一个 MemberExpression。成员是 InnerModel,表达式是 o。

这是一些获取 MemberInfos 链的代码

public static void Foo<T, U>(Expression<Func<T, U>> func)
{
    var memberExp = func.Body as MemberExpression;
    while (memberExp != null)
    {
        var memberInfo = memberExp.Member;
        Console.WriteLine(memberInfo.Name);
        memberExp = memberExp.Expression as MemberExpression;
    }
}

当这样调用时:

Foo<Model, String>(o => o.InnerModel.Value);

它将输出:

  • Value
  • 内部模型

This:

Foo<Assembly, int>(a => a.EntryPoint.DeclaringType.AssemblyQualifiedName.Length);

将输出:

  • Length
  • 装配合格名称
  • 声明类型
  • 入口点
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从表达式函数获取父属性 的相关文章

  • 运行需要 MySql.Data 的内置 .NET 应用程序

    我在运行我编写的内置 NET 应用程序时遇到问题 我的应用程序使用最新的 MySql 连接器 该连接器安装在我的系统上 当我尝试将其添加为引用时 该连接器显示为 NET 4 Framwork 组件 当我在环境中以调试模式运行应用程序时 一切
  • Gwan C#,如何获取HTTP标头?

    我需要它来重写 url 以了解我正在处理哪个友好的 url 用于用户代理和其他东西 EDIT public class Gwan MethodImplAttribute MethodImplOptions InternalCall exte
  • C# 5 async/await 线程机制感觉不对?

    为什么让调用线程进入异步方法直到内部 等待 一旦调用异步方法就生成一个线程 这不是更干净吗 这样您就可以确定异步方法会立即返回 您不必担心在异步方法的早期阶段没有做任何昂贵的事情 我倾向于知道某个方法是否要在 我的 线程上执行代码 不管是堵
  • 在 omp 并行 for 循环中使用 unique_ptr 会导致 SEG.FAULT

    采取以下代码 include
  • 将表(行)与 OpenXML SDK 2.5 保持在一起

    我想在 Word 文档中生成多个表 每行 2 行 但我想将这两行保留在一起 如果可能的话 new KeepNext 第一行不起作用 new KeepNext 第一行的最后一段不起作用 new CantSplit 放在桌子上不起作用 在所有情
  • 使用查询表达式对 List 进行排序

    我在使用 Linq 订购这样的结构时遇到问题 public class Person public int ID get set public List
  • MFC:如何设置CEdit框的焦点?

    我正在开发我的第一个简单的 MFC 项目 但我正在努力解决一个问题 想要设置所有的焦点CEdit其中一个对话框中的框 我的想法是 当打开对话框时 焦点位于第一个编辑框上 然后使用 选项卡 在它们之间交换 我看到了方法SetFocus 但我无
  • 将接口转换为其具体实现对象,反之亦然?

    在 C 中 当我有一个接口和几个具体实现时 我可以将接口强制转换为具体类型 还是将具体类型强制转换为接口 这种情况下的规则是什么 Java 和 C 中都允许这两个方向 向下转型需要显式转型 如果对象类型不正确 可能会抛出异常 然而 向上转换
  • 如何对 NServiceBus.Configure.WithWeb() 进行单元测试?

    我正在构建一个 WCF 服务 该服务接收外部 IP 上的请求并将其转换为通过 NServiceBus 发送的消息 我的单元测试之一调用Global Application Start 它执行应用程序的配置 然后尝试将 Web 服务解析为 验
  • C#6 中的长字符串插值行

    我发现 虽然字符串插值在应用于现有代码库的字符串 Format 调用时非常好 但考虑到通常首选的列限制 字符串对于单行来说很快就会变得太长 特别是当被插值的表达式很复杂时 使用格式字符串 您将获得一个可以拆分为多行的变量列表 var str
  • 使用具有抗锯齿功能的 C# 更改抗锯齿图像的背景颜色

    我有一个图像需要更改背景颜色 例如 将下面示例图像的背景更改为蓝色 然而 图像是抗锯齿的 所以我不能简单地用不同的颜色替换背景颜色 我尝试过的一种方法是创建第二个图像 仅作为背景 并更改其颜色并将两个图像合并为一个图像 但是这不起作用 因为
  • 为什么 Cdecl 调用在“标准”P/Invoke 约定中经常不匹配?

    我正在开发一个相当大的代码库 其中 C 功能是从 C P Invoked 的 我们的代码库中有很多调用 例如 C extern C int stdcall InvokedFunction int 使用相应的 C DllImport CPlu
  • 英文日期差异

    接近重复 如何计算相对时间 https stackoverflow com questions 11 how do i calculate relative time 如何在 C 中计算某人的年龄 https stackoverflow c
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • 使用 lambda 函数更改属性值

    我可以使用 lambda 函数循环遍历类对象列表并更改属性值 对于所有对象或满足特定条件的对象 吗 class Student object def init self name age self name name self age ag
  • .NET 4 的条件编译[重复]

    这个问题在这里已经有答案了 可能的重复 条件编译和框架目标 https stackoverflow com questions 2923210 c sharp conditional compilation and framework ta
  • 在 C#.NET 中安全删除文件

    在我正在做的一个项目中 我想为用户提供 安全 删除文件的选项 例如 用随机位或 0 覆盖它 在 C NET 中是否有一种简单的方法可以做到这一点 效果如何 你可以调用系统内部删除 http technet microsoft com en
  • LINQ 中的“from..where”或“FirstOrDefault”

    传统上 当我尝试从数据库中获取用户的数据时 我使用了以下方法 在某种程度上 DbUsers curUser context DbUsers FirstOrDefault x gt x u LoginName id string name c
  • 来自 3rd 方库的链接器错误 LNK2019

    我正在将旧的 vc 6 0 应用程序移植到 vs2005 我收到以下链接器错误 我花了几天时间试图找到解决方案 错误LNK2019 无法解析的外部符号 imp 创建AwnService 52 在函数 public int thiscall
  • 如何使用placement new重新初始化该字段?

    我的课程包含字段 private OrderUpdate curOrderUpdate 我一遍又一遍地使用它 经常需要重新初始化 for int i 0 i lt entries size i auto entry entries i ne

随机推荐