我按照 Entity Framework 教程编写了一个 ApplicationConfig 模型(这是简化的)-
public class ApplicationConfig
{
public ApplicationConfig()
{
this.Users = new Collection<User>();
this.Roles = new Collection<Role>();
}
public string Namespace { get; set; }
public virtual ICollection<User> Users { get; set; }
public virtual ICollection<Role> Roles { get; set; }
}
public class User
{
public User()
{
this.Roles = new Collection<Role>();
this.ApplicationConfigs = new Collection<ApplicationConfig>();
}
public int UserId { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public virtual ICollection<Role> Roles { get; set; }
public virtual ICollection<ApplicationConfig> ApplicationConfigs { get; set; }
}
我有一种方法可以检查特定应用程序的用户名/密码 -
public User ValidateUser(string applicationNamespace, string username, string password)
{
var applicationConfig = GetApplicationConfig(applicationNamespace);
User user = null;
if (applicationConfig != null)
{
user = applicationConfig.Users.FirstOrDefault(u => u.Username.ToLower() == username && u.Password == password);
}
return user;
}
我可能有成百上千的应用程序用户,但对于此密码检查,我只希望返回匹配的用户。
ICollection 和上面的查询是否可以用于此目的?
我主要担心的是 applicationConfig.Users
将填充所有数千个用户,即使我只想查询一个。
或者我应该使用 IQueryable 或 IEnumerable 还是其他什么?
最佳答案
看起来不太好。您的担忧是有道理的,您必须使用 IQueryable<User>
最终回到DbSet<User>
(或 ObjectSet<User>
)您的 Entity Framework DbContext
(或 ObjectContext
),以确保在加载数千个用户后,您实际上查询的是数据库中的用户,而不是内存中的用户。
我不明白你的架构 ApplicationConfig
确切地说,但是你必须在某个地方调用:
user = context.Users.FirstOrDefault(u =>
u.Username.ToLower() == username && u.Password == password);
基本上是相同的 LINQ,但带有 context
(=您派生的实例 DbContext
(或 ObjectContext
))而不是 applicationConfig
.这将被翻译成在数据库中过滤用户的 SQL 查询。
编辑
如果ApplicationConfig
类是模型和数据库中与 User
有关系的实体s 和 Role
s 您仍然可以根据凭据和验证用户 applicationNamespace
通过单个数据库查询,而无需加载应用程序的所有 用户。例如,它可能看起来像这样:
public User ValidateUser(string applicationNamespace,
string username, string password)
{
return context.ApplicationConfigs
.Where(a => a.Namespace == applicationNamespace)
.Select(a => a.Users
.Where(u => u.Username.ToLower() == username &&
u.Password == password)
.FirstOrDefault())
.FirstOrDefault();
}
或者 - 如果您提供 User
实体ApplicationConfigs
集合(根据您在下面的评论,我假设一个用户帐户可以参与多个应用程序 -> 多对多关系)- 您可以像这样编写查询:
public User ValidateUser(string applicationNamespace,
string username, string password)
{
return context.Users
.FirstOrDefault(u =>
u.ApplicationConfigs.Any(a => a.Namespace == applicationNamespace) &&
u.Username.ToLower() == username && u.Password == password);
}
我更喜欢后一个版本,因为如果需要,您可以通过添加 Include(u => u.Roles)
轻松包含用户的角色。在 context.Users
之后.
无论如何,关键是要有一个 context
可一步执行完整验证。不要像加载 ApplicationConfig
那样把它分成两部分首先与所有用户一起,然后从加载的 Users
中归档用户收藏。
关于c# - 搜索单个结果时与 Entity Framework 一起使用的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16722636/