在项目中根据用户的角色查询出所拥有的菜单,但这时一个用户可能有多个角色,而每个角色可能有重复的菜单,所以这时候就需要吧重复的菜单去掉.
一开始的写法是这样:
//角色菜单
var list = (from m in tbm.LoadEntities(p => p.IsDelete == false).OrderBy(p => p.Orders).ToList()
join p in tbper.LoadEntities(p => p.IsDelete == false && p.IsEnable == true).ToList()
on m.ModuleID equals p.ModuleID
join ru in tbru.LoadEntities().ToList()
on p.RoleID equals ru.RoleID
join u in tbuser.LoadEntities(p => p.UserID == userid).ToList()
on ru.UserID equals u.UserID
select new MenuHelper
{
Icon = m.Icon,
IsEnable = true,
ModuleID = m.ModuleID,
ModuleName = m.ModuleName,
ModuleUrl = m.ModuleUrl,
ParentID = m.ParentID
}).Distinct().ToList();
可是发现这样去重无效,查阅资料解释如下:
Distinct()默认的比较器在比较引用类型时是通过比较对象的引用来确认对象是否相等.
很显然,实例序列中的各个元素的引用是不相等的,因此比较器会认为,序列中的全部元素都不相同,因此不会进行去重操作。
//
// 摘要:
// 通过使用默认的相等比较器对值进行比较返回序列中的非重复元素。
//
// 参数:
// source:
// 要从中移除重复元素的序列。
//
// 类型参数:
// TSource:
// source 中的元素的类型。
//
// 返回结果:
// 一个 System.Collections.Generic.IEnumerable<T>,包含源序列中的非重复元素。
//
// 异常:
// System.ArgumentNullException:
// source 为 null。
public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source);
//
// 摘要:
// 通过使用指定的 System.Collections.Generic.IEqualityComparer<T> 对值进行比较返回序列中的非重复元素。
//
// 参数:
// source:
// 要从中移除重复元素的序列。
//
// comparer:
// 用于比较值的 System.Collections.Generic.IEqualityComparer<T>。
//
// 类型参数:
// TSource:
// source 中的元素的类型。
//
// 返回结果:
// 一个 System.Collections.Generic.IEnumerable<T>,包含源序列中的非重复元素。
//
// 异常:
// System.ArgumentNullException:
// source 为 null。
public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer);
看下Distinct的第二个重载,支持我们自定义去重.代码如下:
/// <summary>
/// 构建一个去重类
/// </summary>
public class MenuHelperComparer : IEqualityComparer<MenuHelper>
{
/// <summary>
/// 重写
/// 判断两个菜单的id是否相等 相等则为同一条数据 所以去掉
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public bool Equals(MenuHelper x, MenuHelper y)
{
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
return x.ModuleID == y.ModuleID ;
}
public int GetHashCode(MenuHelper student)
{
return student.ToString().GetHashCode();
}
}
调用方式:
//没有用户菜单 加载角色菜单
//在这里实例我们的自定义去重类
Mlist = list.Distinct(new MenuHelperComparer()).ToList();