0

我对 LINQ 有一些问题,也许有人得到了答案

string[] roleNames = Roles.GetRolesForUser(currentUserName);


result = context.MenuRoles.Select(mr => new MenuGenerateViewModel
{
    MenuID = mr.MenuID,
    MenuNazwa = mr.Menu.MenuNazwa,
    MenuKolejnosc = mr.Menu.MenuKolejnosc,
    MenuStyl = mr.Menu.MenuStyl,
    MenuParentID = mr.Menu.MenuParentID,
    MenuActive = mr.Menu.MenuActive,
    MenuActionName = mr.Menu.MenuAction.MenuActionName,
    MenuControlName = mr.Menu.MenuControl.MenuControlName,
    RoleName = mr.Role.RoleName,
    RoleID = mr.RoleID,
    MenuID = mr.MenuID
})
.Where(mr => mr.MenuActive == true)
.ToList();

如何仅比较string[] roleNames并仅在匹配时返回。问题总是出现在用户担任 2 个或更多角色时。

发送答案

4

3 回答 3

2

如果我理解您的要求,请在您的Where条款中添加第二个条件:

        .Where(mr => mr.MenuActive && roleNames.Contains(mr.Role.RoleName))
于 2012-06-28T14:06:58.970 回答
1

您最好切换您的Where子句,Select原因很简单,您将不会从不需要的数据库记录中检索。

result = context.MenuRoles.Where(mr => mr.MenuActive 
                    && roleNames.Contains(mr.Role.RoleName))
                .Select(mr => ... )
                .ToList();

这将生成一个只选择必要记录的 sql,而不是选择整个批次然后过滤它。尝试并观察 SQL 分析器以查看差异(在任何情况下使用 EF 的有用技能)

于 2012-06-28T14:15:02.430 回答
0

在这里有才华的人的帮助下,达到了目标。

string[] roleNames = Roles.GetRolesForUser(currentUserName);


result = context.MenuRoles
    .Where(mr => mr.Menu.MenuActive && roleNames.Contains(mr.Role.RoleName))
    .Select(mr => new MenuGenerateViewModel
    {
        MenuID = mr.MenuID,
        MenuNazwa = mr.Menu.MenuNazwa,
        MenuKolejnosc = mr.Menu.MenuKolejnosc,
        MenuStyl = mr.Menu.MenuStyl,
        MenuParentID = mr.Menu.MenuParentID,
        MenuActive = mr.Menu.MenuActive,
        MenuActionName = mr.Menu.MenuAction.MenuActionName,
        MenuControlName = mr.Menu.MenuControl.MenuControlName,
        RoleName = mr.Role.RoleName
    })
    .ToList();

var userresult = context.MenuUsers
    .Where(mr => mr.Menu.MenuActive && mr.User.Username == currentUserName)
    .Select(mr => new MenuGenerateViewModel
    {
        MenuID = mr.MenuID,
        MenuNazwa = mr.Menu.MenuNazwa,
        MenuKolejnosc = mr.Menu.MenuKolejnosc,
        MenuStyl = mr.Menu.MenuStyl,
        MenuParentID = mr.Menu.MenuParentID,
        MenuActive = mr.Menu.MenuActive,
        MenuActionName = mr.Menu.MenuAction.MenuActionName,
        MenuControlName = mr.Menu.MenuControl.MenuControlName,
        Username = mr.User.Username
    })
    .ToList();

在这里,通过组成员资格和直接分配给菜单本身,获取您有权访问的所有菜单。

// Kick all duplicates
var noduplicates = result.Concat(userresult)
                          .Distinct(new RoleMenuGenerateComparer());

因为通常我们不希望菜单中有重复项,所以我们将其删除。为了让它正常工作,我们需要实现 IEqualityComparer (你可以阅读这一点)

public class RoleMenuGenerateComparer : IEqualityComparer<MenuGenerateViewModel>
{

    public bool Equals(MenuGenerateViewModel x, MenuGenerateViewModel y)
    {
        //Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        //Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        //Check whether the products' properties are equal.
        return x.MenuNazwa == y.MenuNazwa && x.MenuID == y.MenuID;
    }

    public int GetHashCode(MenuGenerateViewModel menuGenerateViewModel)
    {
        if (Object.ReferenceEquals(menuGenerateViewModel, null)) return 0;

        int hashMenuName = menuGenerateViewModel.MenuNazwa == null ? 0 : menuGenerateViewModel.MenuNazwa.GetHashCode();

        int hashMenuID = menuGenerateViewModel.MenuID == null ? 0 : menuGenerateViewModel.MenuID.GetHashCode();

        return hashMenuName ^ hashMenuID;

    }

}

当然我相信你可以优化这段代码,但目前我有这样的东西。

全部发送以寻求帮助。

于 2012-06-29T10:12:30.703 回答