访问表达式主体成员以构建表达式树

2023-12-24

尝试使用表达式树按表达式构建订单。但我无法访问查询结果类的表达式主体属性。 这是类结构:

public class AssetFileRecord : IAuditable, IEntity, INavigateToCustomValues
{
    public AssetFileRecord()
    {
        this.UpdatedTimeStamp = DateTime.UtcNow;
    }

    public AssetFileRecord GetRecord()
    {
        return this;
    }

    public Guid Id { get; set; }
    public int DisplayId { get; set; }
    public string AssetTagNumber { get; set; }
    [JObjectIgnore]
    public virtual Account Account { get; set; }
    public string AccountNumber => Account?.AccountNumber;
    public string AuditTrail { get; set; }
    public string OldTagNumber { get; set; }
    public ActivityCode ActivityCode { get; set; }

    [JObjectIgnore]
    public virtual ICollection<AssetFileRecordDepreciation> AssetFileRecordDepreciations { get; set; }
    // Depreciation Records
    public double? AccumulatedDepreciation => Depreciation()?.AccumulatedDepreciation;
    public DateTime? DepreciationAsOfDate => Depreciation()?.DepreciationAsOfDate;
    public double? LifeMonths => Depreciation()?.LifeMonths;
    public double? DepreciationBasis => Depreciation()?.DepreciationBasis;
    public double? PeriodDepreciation => Depreciation()?.PeriodDepreciation;

    private AssetFileRecordDepreciation Depreciation()
    {
        return AssetFileRecordDepreciations?.AsQueryable()?.OrderBy(d => d.AssetFileDepreciationBook.BookNo)?.FirstOrDefault();
    }
}

我无法访问 AccountNumber 属性,它是 AssetFileRecord 虚拟属性的属性。

下面是当前的代码,适用于任何其他非表达式主体属性。

var type = typeof(T);
var property = type.GetProperty(sortProperty, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
var typeArguments = new[] { type, property.PropertyType };
var methodBase = isFirstOrderTerm ? "OrderBy" : "ThenBy";
var methodName = sortOrder == ListSortDirection.Ascending ? methodBase : $"{methodBase}Descending";
var resultExp = Expression.Call(typeof(Queryable), methodName, typeArguments, source.Expression, Expression.Quote(orderByExp));

return source.Provider.CreateQuery<T>(resultExp);

Expression.Call 不会计算出有效的 SQL 查询,而是引发异常。

((System.Data.Entity.Infrastructure.DbQuery<AssetFileRecord>)records).Sql = '((System.Data.Entity.Infrastructure.DbQuery<AssetFileRecord>)records).Sql' threw an exception of type 'System.NotSupportedException'

预期结果:它应该在最后生成的表达式树中附加一个 order by 表达式;虽然它未能这样做,但当尝试通过表达式主体属性成员进行排序时。

有人可以帮我让它工作吗?


你的方法有两个问题。首先,您不能在 Linq 表达式中使用 null 传播运算符。测试这段代码:

var account = new Account();
// will cause "error CS8072: An expression tree lambda may not contain a null propagating operator"    
Expression<Func<string>> accountNumber = () => account?.AccountNumber;

第二个也是主要的问题是你的AccountNumber将被编译成get_AccountNumber方法,并且您无法使用 Linq to SQL 调用任意方法。您可以测试这段代码:

public class AssetFileRecord
{
  //...
  public string AccountNumber => Account != null ? Account.AccountNumber : null;
}

虽然可以编译它,但它会产生相同的运行时异常。

解决此问题的一种可能方法是创建一个包含复杂属性表达式的映射:

var map = new Dictionary<string, Expression>
{
    {
        "AssetFileRecord.AccountNumber", // type and property
        (Expression<Func<AssetFileRecord, string>>) (
            afr => afr.Account != null ? afr.Account.AccountNumber : null
        )
    }
};

现在您可以重写构建动态的方法OrderBy关于这张地图:

private static IQueryable<T> DynamicOrderBy<T>(
    IQueryable<T> source,
    string sortProperty,
    Dictionary<string, Expression> map)
{
    var type = typeof(T);
    var parameter = Expression.Parameter(type, "p");
    var property = type.GetProperty(sortProperty, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

    Expression whereLambda;
    if (!map.TryGetValue($"{type.Name}.{sortProperty}", out whereLambda))
    {
        var propertyAccess = Expression.MakeMemberAccess(parameter, property);
        whereLambda = Expression.Lambda(propertyAccess, parameter);
    }
    // else we just using a lambda from map

    // call OrderBy
    var query = Expression.Call(
        typeof(Queryable),
        "OrderBy",
        new[] {type, property.PropertyType},
        source.Expression,
        whereLambda
    );

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

访问表达式主体成员以构建表达式树 的相关文章

  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐

  • 为什么Java中局部变量没有初始化?

    Java 的设计者是否认为局部变量不应该被赋予默认值 说真的 如果实例变量可以被赋予默认值 那么为什么我们不能对局部变量做同样的事情呢 它还会导致问题 如中所述对博客文章的这条评论 http javahowto blogspot com 2
  • 合并两个重叠列表并保持顺序的 Pythonic 方法

    好吧 我有两个列表 如下所示 他们可以并且将会有重叠的项目 例如 1 2 3 4 5 4 5 6 7 这里将not是重叠中的附加项目 例如 这将not发生 1 2 3 4 5 3 5 4 5 6 7 这些列表不一定是有序的 也不一定是唯一的
  • 如何将纬度/经度对转换为 PostGIS 地理类型?

    我正在尝试将一堆纬度 经度对加载到 PostGIS 地理类型中 以便能够按位置查询 特别是我有一个带有浮动纬度和经度列的表格以及一个geography Point 4326 柱子 我想要做 update mytable set geogra
  • 如何在单个画布android中移动多个位图

    我想在同一画布上移动多个位图 使用下面的代码 我可以在触摸屏幕时移动一个位图 但是 我无法识别位图上的触摸事件 因此我无法移动特定的位图 public class DrawTopologyView extends View Paint pa
  • Rails 7.0 + esbuild:运行应用程序出现错误:找不到命令“build”

    新生成的带有 esbuild 选项的 Rails 7 0 在启动时出错 rails new project name javascript esbuild css tailwind 在创建新的 Rails 7 项目时 我尝试使用以下命令启动
  • android.intent.action.DOWNLOAD_COMPLETE 是显式广播吗?

    我的应用程序 targetSdk 25 在清单中定义了一个广播接收器 如下所示
  • 如何在剃刀视图上设置必填字段?

    我想将 data val required 和 data val 属性添加到 html textbox 或 Html EditorFor 元素 是否可以不重写视图 通常您不应该重写视图来实现这一点 您应该使用相应的验证属性来装饰视图模型属性
  • 如何在 ipython-notebook 中获取 sympy 表达式的乳胶表?

    我正在使用 sympy 从多个表达式中收集术语 并希望将结果 在 ipython notebook 内 格式化在一个表中 其中术语位于最左边的列中 后续的每一列代表一个表达式 该列中的条目来自dict由返回sympy collect sym
  • 如何将 Phantom 钱包连接到我的 Flutter Web 应用程序?

    我一直在尝试将 Flutter Web 应用程序连接到 Phantom 钱包 但没有成功 尚未发布 pub dev 软件包来实现此目的 并且无法弄清楚如何使用 dart js 互操作来实现此目的 想知道是否有人已经弄清楚了 我有一段 粗略的
  • 返回活动时如何保留 Android ListView 滚动位置? [复制]

    这个问题在这里已经有答案了 可能的重复 返回 ListView 时保持 保存 恢复滚动位置 https stackoverflow com questions 3014089 maintain save restore scroll pos
  • 加权词嵌入是什么意思?

    In the paper http www aclweb org anthology S17 2100我正在努力实施 它说 在这项工作中 使用三种类型的文本对推文进行建模 表示 第一个是词袋模型 权重为 tf idf 词频 逆文档频率 部分
  • 如何更新 pyqtgraph 中的绘图?

    我正在尝试使用 PyQt5 和 pyqtgraph 拥有一个用户界面 我制作了两个复选框 每当我选择它们时 我想绘制代码中可用的两个数据集之一 每当我取消选择按钮时 我希望它清除相应的曲线 有两个带有文本的复选框A1 and A2他们每个人
  • Silverlight 中的同步 WebClient 下载

    我需要下载一个字符串 特别是来自 PHP Web 服务的 JSON 数组结果 作为返回字符串的函数 而不是 DownloadStringAsync 我需要这个 因为我正在编写一个下载字符串的函数 然后将其转换为 JsonArray 我正在使
  • Firebase Spark 版本中可以有多少个项目?

    我正在尝试添加第三个项目 但我不断收到此错误 您已经超出了可以创建的免费项目的最大数量 尝试通过项目设置删除一些项目或请求增加项目限制 我已通过项目设置删除了所有多余的项目 希望消除此错误 但它仍然存在 我不想要求更多的项目并且必须付费 我
  • 强制执行密码要求

    我想检查用户是否成功满足以下要求 密码至少有8个字符 由 1 个大写字母和 1 个小写字母组成 我该怎么做 我正在使用下面的 PHP 脚本 if strlen password lt 8 false else if preg match 0
  • 生成唯一 ID(检查或不检查)? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 考虑 youtube 视频网址 例如 e g http www youtube com watch v JVkaMqD5mI feature r
  • JavaFX 两个圆之间的距离并不断更新属性

    为了进行作业 我创建了 2 个可拖动的圆圈 并使用 javaFX 将它们连接起来 我需要添加计算两个圆之间的距离 或线的长度 的文本 并且当我拖动圆时该文本需要不断更新 但这就是我陷入困境的地方 Circle circle1 new Cir
  • 使用 PrintWindow API 截取屏幕截图(客户端区域)

    我正在使用 PrintWindow API 截取特定窗口 hwnd 的屏幕截图 这工作得很好 它可以截取整个窗口的屏幕截图 我的问题是 我的窗口高度是 742 宽度是 653 如果我想在窗口中间的某个位置 不是从 0 0 处 截取屏幕截图
  • 关于 GEKKO 中条件语句('m.if3')的问题

    我想在 GEKKO 代码中添加一些条件语句 我用 m if3 添加了以下语句 但是 它返回了语法错误 如果没有条件语句 我就不会出现这种错误 R1 1 m if3 R1 GEKKO m GEKKO remote False print m
  • 访问表达式主体成员以构建表达式树

    尝试使用表达式树按表达式构建订单 但我无法访问查询结果类的表达式主体属性 这是类结构 public class AssetFileRecord IAuditable IEntity INavigateToCustomValues publi