使用string []进行良好的LINQ查询

时间:2012-06-28 13:59:41

标签: asp.net-mvc asp.net-mvc-3 linq entity-framework authentication

我在使用LINQ时遇到了一些问题,maby有人得到了答案

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个或更多角色时。

答案的答案

3 个答案:

答案 0 :(得分:2)

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

        .Where(mr => mr.MenuActive && roleNames.Contains(mr.Role.RoleName))

答案 1 :(得分:1)

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

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

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

答案 2 :(得分: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(U可以读到这一点)

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;

    }

}

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

Tx全部求助。