实体框架多对多顺序

时间:2018-10-24 11:59:21

标签: entity-framework

我有3个表:Users,Roles和一个中间表UsersRoles。如何根据用户的角色名称订购用户?

public List<USERS> Find(UserFilter filter, string sortExpression, int maxRows, int startIndex)
{
            var query = db.USERS.Include("ROLES").AsQueryable();

            query = ApplyFilter(query, filter);
            query = query.OrderBy(sortExpression);
            query = ApplyPaging(query, maxRows, startIndex);

            var result = query.ToList();
            return result;
}

private IQueryable<USERS> ApplyOrder(IQueryable<USERS> query, UserFilter filter)
{
        // what should I do here to sort/group according to role name ?
}

private IQueryable<USERS> ApplyFilter(IQueryable<USERS> query, UserFilter filter)
{
        if (!string.IsNullOrEmpty(filter.UserName))
                    query = query.Where(u => u.USERNAME == filter.UserName);
}

private IQueryable<USERS> ApplyPaging(IQueryable<USERS> query, int maxRows, int startIndex)
{
            var result = query;
            if (maxRows != 0)
                result = query.Skip(startIndex).Take(maxRows);
            return result;
}

我正在从控制器中调用Find方法,并且正在使用AsQueryable,那么如何根据用户的角色对用户进行分组(应根据角色名称对角色进行排序)?我应该用ApplyOrder方法写什么?

1 个答案:

答案 0 :(得分:1)

考虑以下示例:

var users = new user[]
{
     new user()
     {
         Name = "Jan",
         Roles = new Role[]
         {
             new Role() {Name = "Supervisor},
             new Role() {Name = "Teacher"},
         }
     },
     new user()
     {
         Name = "Pierre",
         Roles = new Role[]
         {
             new Role() {Name = "Student"},
             new Role() {Name = "Scholar"},
         }
     }
}
  

如何根据用户的角色名称订购用户?

什么意思?您是否需要具有角色的用户,这些角色按名称排序?还是您想要按名称与用户一起订购角色?

无论如何,如果您首先遵循实体框架代码的约定,那么多对多的类将类似于以下内容:

class User
{
    public int Id {get; set;}
    public string Name {get; set;}

    // every User has zero or more Roles (many-to-many)
    public virtual ICollection<Role> Roles {get; set;}
}
class Role
{
    public int Id {get; set;}
    public string Name {get; set;}

    // every Role has zero or more Users (many-to-many)
    public virtual ICollection<User> Users {get; set;}
}
class MyDbcontext : DbContext
{
    public DbSet<User> Users {get; set;}
    public DbSet<Role> Roles {get; set;}
}
  

在实体框架中,表的列由   非虚拟属性。虚拟属性代表关系   在表格之间。

对于实体框架而言,这足以检测到您打算建立多对多关系。实体框架将为您创建连接表,并在需要时使用此表。

可能是您想要表和列的其他名称,在这种情况下,您将需要流利的API或属性。但是这些类将是相似的。

按名称顺序授予用户角色

var result = dbContext.Users
    .Where(user => ...)                    // only if you don't want all Users
    .Select(user => new
    {
         // select only the properties that you plan to use
         Id = user.Id,
         Name = user.Name,

         Roles = user.Roles
             .Where(role => ...)           // only if you don't want all Roles
             .OrderBy(role => role.Name)
             .Select(role => new
             {   // again: select only the properties you plan to use
                 Id = role.Id,
                 Name = role.Name,
             })
             .ToList(),
    });

查询中较慢的部分之一是将所选数据传输到本地进程。因此,明智的选择是不要选择比实际使用的数据更多的数据。如果使用include来获取数据,则选择该类的所有属性,包括外键。

例如,如果您以所有学生的身份获取ID为4的教师,则您将知道他的1000个Students中的每一个都有一个值为4的外键TeacherId。运输所有这些外键!

  

建议:查询数据时,请使用Select选择您要使用的属性   实际计划使用。如果您打算更改Include,请仅使用{{1}}   包含的对象