0

I am trying to fill a dropdown with a list of regions that come from a database. The regions are coming from a table where there can be many rows with the same region, so I am using .Distinct() to display only 1 of each in the dropdown. Lets say there are 100 NORTHWEST's in the database. I am using .Distinct() to group them all together so just one NORTHWEST is displayed in the dropdown.

I added the ability to disable and enable regions, which I don't want to affect how they are viewed in the dropdown, but is used for other functionality. The user has the ability to disable or enable any of the 100 in the model (may not make sense, but it has its purpose). They are enabled and disabled with a bit value in the database. The issue comes if there is at least one NORTHWEST enabled and one disabled. Then what I am calling RegionState has a true value and a false value meaning that it displays twice in the dropdown because they are distinct from eachother.

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);

ViewModel:

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

Model:

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

How could I use .Distinct() to only filter based on the name, while allowing regions with both a true and false RegionState to appear as one in the dropdown. I need to keep RegionState in the viewmodel.

Let me know if you have any questions. May be a bit confusing.Thanks!

2
  • please show how you are defining your view mdoels. Commented Aug 19, 2015 at 16:40
  • If you just need the name why include the region state? Commented Aug 19, 2015 at 16:57

2 Answers 2

1

Filter it before applying distinct using Where

viewModel.Regions = context.Where(r => r.PropertyThatIndicatesItIsEnabled)
                           .Select(r => new Region { Name = r.Region, RegionState = r.RegionState })
                           .Distinct()
                           .OrderBy(r => r.Name)
Sign up to request clarification or add additional context in comments.

1 Comment

I believe the PropertyThatIndicatesItIsEnabled is RegionState.
0

How could I use .Distinct() to only filter based on the name, while allowing regions with both a true and false RegionState to appear as one in the dropdown

EDIT As noted by @juharr, below methods wouldn't work with entity framework, Better replace your .Distinct() with .GroupBy(r=>r.Name).Select(g=>g.First())


Implement IEqualityComparer<Region> and call Distinct() as 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();
    }
}

You can also write a custom DistinctBy extension method

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)));
}

Then you can use it as .DistinctBy(region=>region.Name)

2 Comments

I doubt that will work with EF as it will not know how to translate that to SQL. See this quesiton
@juharr You are right. But OP may want to use it after materializing the query

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.