asp.net mvc获取关系数据的更好方法

时间:2015-11-06 14:24:25

标签: c# asp.net-mvc entity-framework

我正在构建一个asp.net mvc网站,允许用户(具有经理角色)添加/管理其他用户

为此,我已将名为ManagerUsers的关系表添加到包含经理ID和用户ID的数据库中。当经理邀请用户时,数据存储在ManagerUsers表中。

当经理查看用户时,我正在执行以下操作:

using (var context = new ApplicationDbContext())
{
    Guid myId = Guid.Parse(User.Identity.GetUserId());
    var userIds = context.ManagersUsers.Where(u => u.ManagerId == myId).Select(u => u.UserId.ToString()).ToList();

    var userProfiles = context.Users.Where(t => userIds.Contains(t.Id)).ToList();

    return View(userProfiles);
}

这样可行,但似乎有点缓慢而且冗长。有谁知道更好的方法吗?

编辑:基于一些回复,我想我需要澄清我要问的问题。我想知道的是,是否有更好的方法来获取管理下的用户列表,而不是从ManagerUsers表中获取用户ID列表,然后从Users表中的所有用户中查找它们?也许有更好的方法来存储这些数据,以便更快地进行检索?

3 个答案:

答案 0 :(得分:1)

您不应该将数据访问代码紧密地耦合到MVC层。这使得更改数据层变得困难,并且在没有访问真实数据库的情况下很难测试MVC。你创建一个允许它们松散耦合的独立层,你会好得多。

interface IMembershipService
{
    List<UserProfile> GetUsersForManager(Guid managerId);
}

class SqlServerMembershipService : IMembershipService
{
    private readonly string ConnectionString;

    public SqlServerMembershipService(string connectionString)
    {
        //Any initialization of the repository goes here
        ConnectionString = connectionString;
    }

    public List<UserProfile> GetUsersForManager(Guid managerId)
    {
        using (var context = new ApplicationDbContext(connectionString))
        {
            var userIds = context.ManagersUsers.Where(u => u.ManagerId == myId).Select(u => u.UserId.ToString()).ToList();

            var userProfiles = context.Users.Where(t => userIds.Contains(t.Id)).ToList();

           return View(userProfiles);
        }
    }
}

您的MVC控制器如下所示:

class UsersController
{
    private readonly IMembershipService MembershipService;

    public UsersController(IMembershipService membershipService)
    {
        MembershipService = membershipService;
    }

    public ActionResult Index()
    {
        Guid myId = Guid.Parse(User.Identity.GetUserId());
        var profiles = MembershipService.GetUsersForManager(myId);
        return View(profiles);
    }
}

了解UsersController现在对SqlServerMembershipService一无所知?它所知道的是,它将通过其构造函数接收一些类,它将处理为它检索数据。它是如何让你的课程。您可以通过说IMembershipService MembershipService = new SqlServerMembershipService来紧密地结合它,但最好使用Dependency Injection为您做到这一点。

答案 1 :(得分:1)

本教程展示了定义与Entity Framework和虚拟属性的关系的示例:

https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application

它看起来像这样:

    public virtual <ApplicationUser> User { get; set; }

这实际上会创建一个与两个模型相关的表格。从这里开始,您应该可以使用ManagerUser.Users或类似的东西来获取用户。我也会按照梅森的例子来实现一个Repository模式。

答案 2 :(得分:0)

万一有人关心,这就是我最终做的事情:

public class ApplicationManager : ApplicationUser
{
    public virtual List<ApplicationUser> Users { get; set; }

    public ApplicationManager()
    {
        Users = new List<ApplicationUser>();
    }
}

public class ApplicationUser : IdentityUser
{
    public virtual ApplicationManager Manager { get; set; }
    ...           
}

这为AspNetUsers表添加了两个字段 - Manager_Id和Discriminator(表明用户是ApplcationManager还是ApplicationUser)。