草庐IT

c# - 表达式列表 <Func<T, TProperty>>

coder 2024-05-30 原文

我正在寻找一种方法来存储 Expression<Func<T, TProperty>> 的集合用于对元素进行排序,然后针对 IQueryable<T> 执行存储的列表对象(底层提供者是 Entity Framework )。

例如,我想做这样的事情(这是伪代码):

public class Program
{
    public static void Main(string[] args)
    {
        OrderClause<User> orderBys = new OrderClause<User>();
        orderBys.AddOrderBy(u => u.Firstname);
        orderBys.AddOrderBy(u => u.Lastname);
        orderBys.AddOrderBy(u => u.Age);

        Repository<User> userRepository = new Repository<User>();
        IEnumerable<User> result = userRepository.Query(orderBys.OrderByClauses);
    }
}

一个 order by 子句(要订购的属性):

public class OrderClause<T>
{
    public void AddOrderBy<TProperty>(Expression<Func<T, TProperty>> orderBySelector)
    {
        _list.Add(orderBySelector);
    }

    public IEnumerable<Expression<Func<T, ???>>> OrderByClauses
    {
        get { return _list; }
    }
}

带有我的查询方法的存储库:

public class Repository<T>
{
    public IEnumerable<T> Query(IEnumerable<OrderClause<T>> clauses)
    {
        foreach (OrderClause<T, ???> clause in clauses)
        {
            _query = _query.OrderBy(clause);
        }

        return _query.ToList();
    }
}

我的第一个想法是转换 Expression<Func<T, TProperty>>成一个字符串(要排序的属性名称)。所以基本上,我没有存储类型列表(这是不可能的,因为 TProperty 不是常量),而是存储一个字符串列表,其中包含要排序的属性。

但这行不通,因为我无法重建 Expression返回(我需要它,因为 IQueryable.OrderBy 将 Expression<Func<T, TKey>> 作为参数)。

我还尝试动态创建表达式(在 Expression.Convert 的帮助下),以获得 Expression<Func<T, object>>但后来我从 Entity Framework 中得到一个异常,说它无法处理 Expression.Convert 语句。

如果可能,我不想使用像 Dynamic Linq Library 这样的外部库.

最佳答案

这是动态/反射解决方案可能适用的少数情况之一。

我想你想要这样的东西? (我已经阅读了字里行间的内容,并在我认为必要的地方对您的结构进行了一些更改)。

public class OrderClauseList<T>
{
    private readonly List<LambdaExpression> _list = new List<LambdaExpression>();

    public void AddOrderBy<TProperty>(Expression<Func<T, TProperty>> orderBySelector)
    {
        _list.Add(orderBySelector);
    }

    public IEnumerable<LambdaExpression> OrderByClauses
    {
        get { return _list; }
    }
}

public class Repository<T>
{
    private IQueryable<T> _source = ... // Don't know how this works

    public IEnumerable<T> Query(OrderClause<T> clauseList)
    {
        // Needs validation, e.g. null-reference or empty clause-list. 

        var clauses = clauseList.OrderByClauses;

        IOrderedQueryable<T> result = Queryable.OrderBy(_source, 
                                                        (dynamic)clauses.First());

        foreach (var clause in clauses.Skip(1))
        {
            result = Queryable.ThenBy(result, (dynamic)clause);
        }

        return result.ToList();
    }
}

关键技巧是让 C# dynamic 为我们执行可怕的重载解析和类型推断。更重要的是,我相信上面的内容,尽管使用了 dynamic,实际上是类型安全的!

关于c# - 表达式列表 <Func<T, TProperty>>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16678057/

有关c# - 表达式列表 <Func<T, TProperty>>的更多相关文章

  1. ruby - 在 Ruby 中实现 `call_user_func_array` - 2

    我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)

  2. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  3. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  4. ruby - RVM 使用列表[0] - 2

    是否有类似“RVMuse1”或“RVMuselist[0]”之类的内容而不是键入整个版本号。在任何时候,我们都会看到一个可能包含5个或更多ruby的列表,我们可以轻松地键入一个数字而不是X.X.X。这也有助于rvmgemset。 最佳答案 这在RVM2.0中是可能的=>https://docs.google.com/document/d/1xW9GeEpLOWPcddDg_hOPvK4oeLxJmU3Q5FiCNT7nTAc/edit?usp=sharing-知道链接的任何人都可以发表评论

  5. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

  6. ruby-on-rails - Nokogiri:使用 XPath 搜索 <div> - 2

    我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll

  7. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  8. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  9. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  10. ruby - 正则表达式将非英文字母匹配为非单词字符 - 2

    @raw_array[i]=~/[\W]/非常简单的正则表达式。当我用一些非拉丁字母(具体来说是俄语)尝试时,条件是错误的。我能用它做什么? 最佳答案 @raw_array[i]=~/[\p{L}]/使用西里尔字符进行测试。引用:http://www.regular-expressions.info/unicode.html#prop 关于ruby-正则表达式将非英文字母匹配为非单词字符,我们在StackOverflow上找到一个类似的问题: https://

随机推荐