草庐IT

c# - 从字符串属性名称创建通用表达式

coder 2024-05-19 原文

我有一个名为 sortColumn 的变量,它包含我想作为查询结果排序依据的列的文本。我还有一个通用存储库,它将包含我要排序的字段的表达式作为参数。我似乎无法从字符串属性名称获取表达式。

所以我拥有的通用存储库包含以下方法

public IEnumerable<TEntity> Get<TOrderBy>(Expression<Func<TEntity, bool>> criteria,
                                          Expression<Func<TEntity, TOrderBy>> orderBy, int pageIndex,
                                          int pageSize,
                                          bool isAssendingOrder = true,
                                          EnumDeletePolicy deletePolicy = EnumDeletePolicy.ExcludeDeleted)

注意此 Get 的第二个参数是 Expression-Func-TEntity, TOrderBy。正如我所提到的,我有一个名为 sortColumn 的变量,它包含我的 TEntity 对象上的一个属性的字符串,我需要将该字符串转换为可以传递给 Get 方法的表达式。

这是我现在拥有的。

        var parameter = Expression.Parameter(typeof(IContract));
        var memberExpression = Expression.Property(parameter, data.SortColumn);
        var lambdaExpression = Expression.Lambda(memberExpression, parameter);

创建一个 LambdaExpression 类型的对象。此 LambdaExpression 的实际类型是 Expression-Func-IContract、字符串(或属性的任何类型 sortColumn)。如果我调用 Get 方法并传入此 LambdaExpression 并将其显式转换为 Expression 类型,那么它将正常工作。问题是我不知道表达式类型是什么,它可能是字符串、整数、整数?等。这完全取决于 sortColumn 属性中特定的属性类型。

你能帮我最后跳转到正确的表达式类型吗?

根据 Marc 的建议进行编辑: 我几乎有这个工作,实际上具体基于它正在工作的问题,但我还有 1 个问题。

作为我要查询的实体类型的 IContract 实际上继承自 IRelationship。如果我从 IContract 接口(interface)指定一个字段,那么上面的代码就可以工作。如果我从 IRelationship 接口(interface)指定一个字段,则以下行失败。

        var memberExpression = Expression.Property(parameter, data.SortColumn);

如果我尝试类似下面的操作,以便从 IRelationship 中获取 MemberExpression,但基于 IContract 构建 Lambda,我会从存储库中收到错误。

        var parameter = Expression.Parameter(typeof(IRelationship));
        var memberExpression = Expression.Property(parameter, data.SortColumn);
        var orderBy = Expression.Lambda(memberExpression, Expression.Parameter(typeof(IContract)));

我收到的错误是“参数 '' 未绑定(bind)到指定的 LINQ to Entities 查询表达式中。”

让它工作的最后一个表达式是这样的

        var parameter = Expression.Parameter(typeof(IContract));
        var memberExpression = Expression.Property(parameter, typeof(IRelationship), data.SortColumn);
        var orderBy = Expression.Lambda(memberExpression, parameter);

所以我需要在 memberExpression 行中指定中间参数,也就是说在继承的 Relationship 接口(interface)中查找属性

最佳答案

您有点需要使用正确的泛型重载 - 这曾经意味着您必须使用 MakeGenericMethod;但是,您也可以使用 dynamic 来避免在这里使用 MakeGenericMethod 的需要,例如(在这种情况下通过 Where,但重要的一点它是如何工作的):

IQueryable<Foo> source = new[] { new Foo { Bar = 123 } }.AsQueryable();
Expression<Func<Foo,bool>> typed =  x=>x.Bar == 123;

LambdaExpression untyped = typed;
IQueryable<Foo> filtered = Queryable.Where(source, (dynamic)untyped);

注意:您不能在此处使用扩展 方法 - 因此您需要使用 Queryable.*

对于使用您的代码的 OrderBy 示例:

var parameter = Expression.Parameter(typeof(Foo));
var memberExpression = Expression.Property(parameter, "Bar");
var lambdaExpression = Expression.Lambda(memberExpression, parameter);
LambdaExpression untyped = lambdaExpression;

IQueryable<Foo> sorted = Queryable.OrderBy(source, (dynamic)untyped);

var all = sorted.ToArray();

重新编辑:

var parameter = Expression.Parameter(typeof(IRelationship));
var memberExpression = Expression.Property(
    Expression.Convert(parameter, typeof(IContract)), data.SortColumn);
var orderBy = Expression.Lambda(memberExpression, parameter);

关于c# - 从字符串属性名称创建通用表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18321019/

有关c# - 从字符串属性名称创建通用表达式的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  3. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  4. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  5. ruby-on-rails - unicode 字符串的长度 - 2

    在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

  6. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  7. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  8. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  9. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  10. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

随机推荐