【问题标题】:C# LINQ query from datatable来自数据表的 C# LINQ 查询
【发布时间】:2016-12-19 15:24:34
【问题描述】:

我正在尝试在我们正在使用的搜索页面上实现 LINQ 查询。从初始查询返回的数据布局如下:

ListID ListName TagId TagValue
1      Name1    1     Tag1
1      Name1    2     Tag2
2      Name2    3     Tag3

基本上,列表是搜索类别,标签是搜索词。我想要做的是带回这个列表,将它分成唯一的列表,然后在页面上显示相关的标签。

我已将数据加载到数据表中,现在我正在尝试将列表名称放入我的 SearchCategories 对象中:

public class SearchCategories
{
    public int SearchCategoryId { get; set; }

    public string SearchCategoryName { get; set; }

    public SearchTags searchTags { get; set; }

    public List<SearchTags> lstSearchTags= new List<SearchTags>();
}

和 SearchTag 类:

public class SearchTags
{
    public int SearchTagId { get; set; }

    public string SearchTagValue { get; set; }
}

然后将标签放入对象的相关列表中。

这是我正在使用的代码:

dtLists.Load(reader);

var distinctValues = dtLists.AsEnumerable()
   .Select(row => new SearchCategories
   {
   SearchCategoryId = row.Field<int>("ListNameID"),
   SearchCategoryName = row.Field<string>("listName")
   })
   .Distinct();

较新的 LINQ,但认为这应该更容易。提前致谢。

【问题讨论】:

  • 看看GroupBy(而不是Distinct)。

标签: c# asp.net linq


【解决方案1】:

这样就可以了:

var result = dtLists.AsEnumerable()
        .GroupBy(m => new
        {
            ListID = m.Field<int>("ListID"),
            ListName = m.Field<string>("ListName")
        }, m => m)
        .Select(m => new
        {
            m.Key.ListID,
            m.Key.ListName,
            Tags = m.Select(x => new { x.Field<int>("TagId"), x.Field<string>("TagValue") })
        });

那你当然要映射到你的类型...

【讨论】:

    【解决方案2】:

    使用GroupBy 应该很容易做到这一点。

    dtLists.AsEnumerable()
        .GroupBy(x => new { ListNameID = x.Field<int>("ListNameID"), ListName = x.Field<string>("ListName") })
        .Select(x => new SearchCategories()
        {
            SearchCategoryId = x.Key.ListNameID,
            SearchCategoryName = x.Key.ListName,
            lstSearchTags = x.Select(y => new SearchTags(){ SearchTagId = y.Field<int>("TagId"), SearchTagValue = y.Field<string>("TagValue") }).ToList()
        });
    

    【讨论】:

      【解决方案3】:

      我不清楚你想要你的输出,基于哪些标准,只是问你是否想要更精确。

      void Main()
      {
          var list = new List<Data>(){
                                  new Data
                                  {
                                     ListId = 1,
                                     ListName = "Name1",
                                     TagId = 1,
                                     TagValue = "Tag1"
                                  },
                                  new Data
                                  {
                                     ListId = 1,
                                     ListName = "Name1",
                                     TagId = 2,
                                     TagValue = "Tag2"
                                  },
                                  new Data
                                  {
                                     ListId = 2,
                                     ListName = "Name2",
                                     TagId = 3,
                                     TagValue = "Tag3"
                                  }};
      
          //this is to group all SearchCategories by SearchCategoryName
          var res = list.Select(x => new SearchCategories
          {
             SearchCategoryId = x.ListId,
             SearchCategoryName = x.ListName
          }).GroupBy(x => x.SearchCategoryName);
      
          //to have just distinct categories one time
          var res2 = list.Select(x => new SearchCategories
          {
              SearchCategoryId = x.ListId,
              SearchCategoryName = x.ListName
          }).Distinct(new SearchCategoriesComparer());
      
          //display your data here based on a Key. The output should be Key=Name1  with two elements inside and the other one with one element Key=Name2
          res.Dump(); 
      
          //display your data here
          res2.Dump(); 
      
      }
      
      public class Data
      {
          public int ListId   {get; set;}
          public string ListName { get; set; }
          public int TagId { get; set; }
          public string TagValue { get; set;}
      }
      
      
      public class SearchCategories
      {
          public int SearchCategoryId { get; set; }
      
          public string SearchCategoryName { get; set; }
      
          public List<SearchTags> lstSubCategories = new List<SearchTags>();
      }
      
      public class SearchCategoriesComparer : IEqualityComparer<SearchCategories>
      {
          public bool Equals(SearchCategories x, SearchCategories y)
          {
              return x.SearchCategoryName == y.SearchCategoryName;
          }
      
          public int GetHashCode(SearchCategories obj)
          {
              return obj.SearchCategoryName.GetHashCode();
          }
      }
      
      
      public class SearchTags
      {
          public string Tag{ get; set;}
      }
      

      【讨论】:

        【解决方案4】:

        尝试以下类似的方法,使用 GroupBy,不确定您的 SearchTags 是什么,因此将 x =&gt; new SearchTags(x) 替换为它的构造方式。

        dtLists.AsEnumerable()
            .Select(row => new {
               SearchCategoryId = row.Field<int>("ListID "),
               SearchCategoryName = row.Field<string>("listName"),
               TagId = row.Field<int>("TagId"),
               TagValue = row.Field<string>("TagValue")
            })
            .GroupBy(x => x.SearchCategoryId)
            .Select(g => new SearchCategories() {
                        SearchCategoryId  = g.Key,
                        SearchCategoryName = g.First().SearchCategoryName,
                        lstSubCategories = g.Select(x => new SearchTags(){ SearchTagId = x.TagId, SearchTagValue = x.TagValue}).ToList()
                        }).ToList();
        

        【讨论】:

        • 这与我一直在尝试的最接近。我用搜索标签属性更新了问题,但我没有正确构建它。
        • 我已经用SearchTags的新结构更新了答案
        猜你喜欢
        • 2011-10-29
        • 2015-07-03
        • 1970-01-01
        • 2023-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多