显示同一表

时间:2015-09-28 14:18:03

标签: c# asp.net asp.net-mvc linq

我想我有一个高级时刻,但我也认为我之前没有遇到过这种情况。我的MVC5 Identity 2.1 Users表中有两列。

UserId | BannedBy (and also an IsBanned bool)

这两个字段都是userid guid字符串。但是,BannedBy引用同一个Users表中的不同用户。

当我显示禁止用户的视图(一个表,每一行是一个被禁止的用户)时,我不想显示BannedBy guid,我想显示该BannedBy guid的相关UserName。但是,我似乎无法弄清楚我需要做什么。

我尝试过ViewModel和方法:

public ActionResult BannedUsers()
    {
        var bannedUsers = db.Users.Where(d => d.IsBanned);

        var model = new BannedUsersViewModel
        {
            BannedUsers = bannedUsers,
            BannedByUserName = GetUserName(bannedUsers.BannedBy)
        };

        return View(model);
    }

然后就像我的viewmodel的外部方法:

var model = new BannedUsersViewModel
        {
            BannedUsers = bannedUsers
        };
        model.BannedByUserName = GetUserName(model.bannedUsers.BannedBy);

然而,似乎我不能使用bannedUsers.BannedBy(我还尝试了以上所有以上的资本B ... BannedUsers.BannedBy)数据才真正被渲染?现在我已经取消了视图模型,并尝试像我的查询中的相关数据连接一样:

db.Users.Join(d => d.BannedBy == d.UserId).Where(d => d.IsBanned); 

(我确定这是关闭的,我只是想给你一个想法)

有谁知道这样做的正确方法?我也在考虑从我的角度调用一个方法,但似乎这会打破MVC规则?

谢谢。

更新:这是GetUserName方法:

public string GetUserName(string userId)
    {
        var result = db.Users.Find(userId);

        return result.UserName;
    }

更新#2:这是BannedUsersViewModel:

public class BannedUsersViewModel
{
    public IEnumerable<ApplicationUser> BannedUsers { get; set; } 
    public string BannedByUserName { get; set; }

}

更新#3:图片: BannedUsers

2 个答案:

答案 0 :(得分:0)

我准备好了。我们可以根据需要修改它(除非我完全偏离基础,在这种情况下,我将删除它,我们都会假装它从未发生过)。这会让你进入球场:

public ActionResult BannedUsers()
{
   var bannedUsers = 
        db.Users
        .Where(d => d.IsBanned)
        .Join(
            db.Users,
            bannee => bannee.BannedBy,
            banner => banner.UserId,
            (bannee, banner) => new BannedUser() 
                { 
                    BannedByUserName = banner.UserName,
                    BannedUser = bannee 
                })
        .AsEnumerable();

   var model = new BannedUsersViewModel
   {
       BannedUsers = bannedUsers
   };

   return View(model);
}

public class BannedUsersViewModel
{
    public IEnumerable<BannedUser> BannedUsers { get; set; }
}

public class BannedUser
{
    public ApplicationUser BannedUser { get; set; } 
    public string BannedByUserName { get; set; }
}

我们的想法是,我们获取所有被禁用的用户,将他们加入禁止这些用户的所有用户,然后由禁止他们的用户进行分组。您最终会得到一组对象,这些对象的用户禁止其他用户及其禁止的用户。

答案 1 :(得分:0)

到目前为止,我在@ lazy的评论中加入了自我加入。我不确定我对它的感觉有多好。基本上,我将此添加到public class ApplicationUser : IdentityUser下的IdentityModels.c:

[ForeignKey("BannedBy")]
public virtual ApplicationUser BannedByUser { get; set; }

然后在我的控制器中,将原始查询更改为列表:

var bannedUsers = db.Users.Where(d => d.IsBanned).ToList();

return View(bannedUsers);

(如果我没有转换为列表,则会抱怨打开多个数据读取器。)然后在我的foreach循环视图中:

@Html.DisplayFor(modelItem => item.BannedByUser.UserName)

热潮: Banned Users

我有点担心性能影响?...特别是对于一个经常使用并且不是那么重要的页面。如果页面没有被调用(比如创建的索引等)会有影响吗?我也有点怀疑,因为身份似乎发生了一些神奇的事情。

无论如何,我仍然对其他想法持开放态度......或对这一想法的想法。再次感谢大家的帮助。