我有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方法写什么?
答案 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}} 包含的对象