【问题标题】:C# Using Strings in LINQ GroupBy Statement for Dynamic PropertiesC# 在动态属性的 LINQ GroupBy 语句中使用字符串
【发布时间】:2019-01-10 20:54:09
【问题描述】:

环境:ASP.net Core 2 Web API 项目。

我有一个查询数据库并返回一个具有很多属性的模型。 一些属性对于每条记录都是唯一的(例如,名称),而另一些则与多个记录相关联(例如,类别、类型等)。

在一天结束的时候,我需要计算出返回的类别的摘要,以及每个类别的记录计数。 通常,我会执行此 SQL,但在这种情况下我不能。

我发现我可以用 LINQ 做到这一点:

例如:

var results = GetSearch(....); //Thing that gets all the results from the database.

var catSummary = results.GroupBy(c => c.Category).ToList();

这很好,但是,我有大约 6 件事情要做。 所以我认为: 我列个清单:

List<string> FilterableAttributes = new List<string>
    {
            "Category",
            "Type",
            "Town"
    }; 

然后像这样遍历模型:

SearchResults searchresults = new SearchResults(); //This is the Model used in the results.
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(searchresults))
{
    var match = FilterableAttributes.FirstOrDefault(stringToCheck => stringToCheck.Contains(prop.Name));
    if (match != null)
    {
        var summary = results.GroupBy(c => c.XXXXXXX).ToList(); //Here is where I'm stuck.
    }
}

哪个应该起作用,我只是不知道如何将属性从模型传递到 GroupBy 语句。 我知道我可以通过“prop.Name”获得该物业的名称 但我似乎无法弄清楚如何使用它。

我也尝试过这样做:

var summary = from r in results 
              group r by r.XXXXXX into g //Unknown how to make this work
              select new { Name = g.Key, Count = g.Count() };

(这可能是我应该走的路,因为它使下一部分更容易)。

这部分代码可能是 API 中请求最多的部分,因此速度很重要。 (我一直在读“慢”反射是多么的)

C# 对我来说是新手,我的背景是 Python。

想法、cmets、想法? 我意识到我可能做错了,因此我提供了一些我想要实现的总体目标的详细信息,而不仅仅是技术问题。

【问题讨论】:

    标签: c# asp.net linq .net-core


    【解决方案1】:

    如果变量 'results' 是用户定义的类型,那么您可以使用 Linq 到如下对象。

    var summary = results.GroupBy(c => c.GetType().GetProperty(category).GetValue(c, null))
    

    如果它是一个数据库对象,那么这可以通过一个简单的 if - else 条件来实现,如下所示。

    SearchResults searchresults = new SearchResults(); 
    foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(searchresults))
    {
        var match = FilterableAttributes.FirstOrDefault(stringToCheck => stringToCheck.Contains(prop.Name));
        if (match != null)
        {
            var summary = new List(); 
            if(prop.Name == "prop1") // Place prop1 in a static constants variable
              {
            summary = results.GroupBy(c => c.yourProperty1).ToList(); 
              }
            else if(prop.Name == "prop2")
              {
                  // go on
              }
        }
    }
    

    【讨论】:

    • 谢谢!经过进一步研究,我似乎遇到了编程风格的限制。在 Python 中,我宁愿编写更少的代码,最少甚至不重复代码,但是 C# 强类型编译器不能以这种方式工作。它强制/鼓励程序员编写更多代码,以便它确切地知道编译时发生的事情。而 Python 在运行时完成所有操作,因此没有性能优势。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-20
    • 1970-01-01
    • 2021-10-06
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多