【问题标题】:Trouble when using C# .Distinct()使用 C# .Distinct() 时出现问题
【发布时间】:2015-11-13 02:01:14
【问题描述】:

我正在尝试使用来自数据库的区域列表填充下拉列表。这些区域来自一个表,其中可以有许多行具有相同的区域,因此我使用.Distinct() 在下拉列表中仅显示其中的一个。假设数据库中有 100 个NORTHWEST。我正在使用.Distinct() 将它们组合在一起,因此下拉菜单中只显示一个NORTHWEST

我添加了禁用和启用区域的功能,我不想影响它们在下拉列表中的查看方式,但用于其他功能。用户可以禁用或启用模型中的 100 个中的任何一个(可能没有意义,但它有其目的)。它们通过数据库中的位值启用和禁用。如果至少启用了一个 NORTHWEST 并且禁用了一个,则会出现问题。然后我所说的 RegionState 有一个真值和一个假值,这意味着它在下拉列表中显示两次,因为它们彼此不同。

var context = new TestContext();
var viewModel = new TestViewModel();

viewModel.Regions = context.Select(r => new Region 
   { Name = r.Region, 
     RegionState = r.RegionState 
   }).Distinct().OrderBy(r => r.Name);

视图模型:

    public class TestViewModel
    {
    public IEnumerable<Region> Regions;
    }

型号:

    public class Region
    {
    public String Name;
    public bool RegionState { get; set; }
    }

如何使用.Distinct() 仅根据名称进行过滤,同时允许具有真假RegionState 的区域在下拉列表中显示为一个。 我需要将 RegionState 保留在视图模型中。

如果您有任何问题,请告诉我。可能有点混乱。谢谢!

【问题讨论】:

  • 请说明您是如何定义视图模型的。
  • 如果您只需要名称,为什么要包含区域状态?

标签: c# asp.net-mvc entity-framework model viewmodel


【解决方案1】:

在使用 Where 应用 distinct 之前过滤它

viewModel.Regions = context.Where(r => r.PropertyThatIndicatesItIsEnabled)
                           .Select(r => new Region { Name = r.Region, RegionState = r.RegionState })
                           .Distinct()
                           .OrderBy(r => r.Name)

【讨论】:

  • 我相信PropertyThatIndicatesItIsEnabledRegionState
【解决方案2】:

我如何使用 .Distinct() 仅基于名称进行过滤,同时允许具有真假 RegionState 的区域在下拉列表中显示为一个

编辑 正如@juharr 所指出的,以下方法不适用于实体框架,最好将您的.Distinct() 替换为.GroupBy(r=&gt;r.Name).Select(g=&gt;g.First())


实现IEqualityComparer&lt;Region&gt;并将Distinct()调用为Distinct(new RegionComparer())

public class RegionComparer : IEqualityComparer<Region>
{
    public bool Equals(Region x, Region y)
    {
        return x.Name == y.Name;
    }

    public int GetHashCode(Region obj)
    {
        return obj.Name.GetHashCode();
    }
}

你也可以编写自定义的 DistinctBy 扩展方法

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
{
    var items = new HashSet<TKey>();
    return source.Where(x => items.Add(selector(x)));
}

那么你就可以把它当成.DistinctBy(region=&gt;region.Name)

【讨论】:

  • 我怀疑这是否适用于 EF,因为它不知道如何将其转换为 SQL。看到这个quesiton
  • @juharr 你是对的。但是 OP 可能想在实现查询后使用它
猜你喜欢
  • 2012-08-29
  • 1970-01-01
  • 2022-10-15
  • 2019-02-23
  • 2023-01-13
  • 2011-08-31
  • 2011-04-22
  • 2019-12-14
  • 1970-01-01
相关资源
最近更新 更多