实体框架从模型</selectlistitem>生成唯一值的列表<selectlistitem>

时间:2013-04-23 15:10:06

标签: asp.net-mvc entity-framework

我有一个名为Roles的模型:

public string CodeRole { get; set; }
public string Organisation { get; set; }
public string LabelRole { get; set; }

CodeRoleLabelRole包含唯一值,但Organisation列包含大约12个类别。我想生成一个下拉列表,允许用户按Organisation进行过滤。

因此,我想使用Entity Framework构建一个查询,该查询返回某种形式的list / array / collection我可以很容易地转换为List<SelectListItem>,同时textvalue相等到不同的Organisation值。

我认为查询看起来像这样:

_context.Roles.GroupBy(r=> r.Organisation)

这会返回IGrouping<string,Roles>个对象,但我不知道如何使用IGrouping

这样我就可以通过List<SelectListItem>ViewBag传递到视图中的下拉列表。

编辑:基于Alexander Manekovskiy回复的最终解决方案

List<Roles> orgs = (List<DimRoles>)_context.Roles.GroupBy(f => f.Organisation).Select(r => r.FirstOrDefault()).ToList();
List<SelectListItem> items = new List<SelectListItem>();

foreach (DimRoles r in orgs) 
    items.Add(new SelectListItem { Text = r.Organisation, Value = r.Organisation });

1 个答案:

答案 0 :(得分:2)

是的,你对GroupBy是对的,但是你需要只从组中选择第一个值:

_context.Roles.GroupBy(r=> r.Organisation).Select(r = r.First())

另一种可能的解决方案是使用Distinct扩展方法:

_context.Roles.Select(r=> r.Organisation).Distinct()

然后要获得List<SelectListItem>,您可以使用选择:

_context.Roles.GroupBy(r=> r.Organisation).Select(r => 
{ 
    var organization = r.First();
    return new SelectListItem() { Name = organization , Value = organization }
}).ToList();

但就个人而言,我更倾向于使用另一种将IEnumerable<T>转换为List<SelectListItem>的扩展方法。这可能是这样的:

public static IEnumerable<SelectListItem> GetList<TEntity>(this IEnumerable<TEntity> collection, Expression<Func<TEntity, object>> keyExpression,
    Expression<Func<TEntity, object>> valueExpression, object selectedValue = null)
{
    var keyField = keyExpression.PropertyName();
    var valueField = valueExpression.PropertyName();

    return new SelectList(collection, keyField, valueField, selectedValue).ToList();
}

然后你可以像这样使用它:

_context.Roles.Distinct(new OrganizationEqualityComparer()).GetList(o => o.Organization, o => o.Organization);

但在这种情况下,您需要实现IEqualityComparer<Role>,这非常简单:

class RoleOrganizationComparer : IEqualityComparer<Role>
{
    public bool Equals(Role x, Role y)
    {
        if (Object.ReferenceEquals(x, y)) return true;
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        return x.Organization == y.Organization;
    }

    public int GetHashCode(Role role)
    {
        //Check whether the object is null 
        if (Object.ReferenceEquals(role, null)) return 0;

        //Get hash code for the Name field if it is not null. 
        return role.Organization == null ? 0 : role.Organization.GetHashCode();
    }
}