【发布时间】:2016-03-12 04:14:55
【问题描述】:
我正在使用实体框架 6 和 MSSQL 服务器数据库维护一个 ASP.NET WebAPI2 应用程序。 IoC 容器是 Castle Windsor。我在我的存储库中有一个方法,用于从 DB 获取用户的一些详细信息。由于我不需要每一列,我想我会使用投影。问题是生成的 SQL 选择了我表中的所有列。 这是 DbContext
public partial class SecurityContext : DbContext
{
public SecurityContext()
: base("name=SecurityContext")
{
}
public virtual DbSet<User> secUsers { get; set; }
}
这里是在存储库中声明/初始化上下文的地方
public class BaseRepository<T> : IRepository<T> where T : class
{
protected DbContext context;
public BaseRepository()
{
context = new SecurityContext();
}
public BaseRepository(DbContext context)
{
this.context = context;
}
//elided
}
这是存储库中的方法
public User FindUserForLoginVerification(string name)
{
var loginInfo = context.Set<User>()
.Where(c => c.LoginName == name)
.Select(c => new
{
LoginName = c.LoginName,
Password = c.HashedPassword,
Salt = c.PasswordHashSalt
})
.SingleOrDefault();
return new User() {
LoginName = loginInfo.LoginName,
HashedPassword = loginInfo.Password,
PasswordHashSalt = loginInfo.Salt
};
}
这是输出 SQL。
SELECT
[Extent1].[UserId] AS [UserId],
[Extent1].[CreatedByUserId] AS [CreatedByUserId],
[Extent1].[Comment] AS [Comment],
[Extent1].[CreatedDate] AS [CreatedDate],
[Extent1].[DefaultCulture] AS [DefaultCulture],
[Extent1].[EmailAddress] AS [EmailAddress],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[IsDeleted] AS [IsDeleted],
[Extent1].[IsExcludedFromPasswordPolicy] AS [IsExcludedFromPasswordPolicy],
[Extent1].[IsChangePassword] AS [IsChangePassword],
[Extent1].[IsLocked] AS [IsLocked],
[Extent1].[LastName] AS [LastName],
[Extent1].[LastPasswordChangeDate] AS [LastPasswordChangeDate],
[Extent1].[LoginName] AS [LoginName],
[Extent1].[NumberOfFailedLoginAttempts] AS [NumberOfFailedLoginAttempts],
[Extent1].[PasswordHash] AS [PasswordHash],
[Extent1].[PasswordHashSalt] AS [PasswordHashSalt]
[Extent1].[UpdatedDate] AS [UpdatedDate]
FROM [dbo].[User] AS [Extent1]
我想我做错了什么,但我不知道是什么。任何想法将不胜感激。
编辑:我刚刚注意到一些奇怪的事情——在生成的 SQL 中没有 WHERE 子句,这意味着所有行都是从数据库中选择的,带到客户端,然后在那里过滤。 编辑 2:使用 LINQ 查询语法生成相同的 SQL。 编辑 3:在编写单元测试后,我手动实例化存储库和服务(而不是将其留给 CastleWindsor),运行测试时生成的 SQL 具有 WHERE 子句。
【问题讨论】:
-
在您的上下文中,集合是如何声明的?他们有
public virtual还是只有public -
为什么是
context.Set<User>()而不是context.secUsers()? -
@GregoryHouseMD 因为在存储库中,上下文作为 DbContext 传递。在回答您的评论之前,我已尝试将其转换为 SecurityContext,但没有产生任何差异。
-
你试过
var loginInfo = context.Set<User>() .Where(c => c.LoginName == name).ToList().Select...吗? -
我注意到通用存储库的行为相同。例如,如果您有类似
context.Set<T>().Where(condition).Select(user => user.Name)的代码,则不会生成 where 子句或投影。
标签: c# sql-server asp.net-web-api entity-framework-6