[英]Entity framework 6 projection generates SQL equivalent to “Select *” and does not produce WHERE clause
I'm maintaining an ASP.NET WebAPI2 application with Entity framework 6 and MSSQL server database. 我正在使用实体框架6和MSSQL服务器数据库维护ASP.NET WebAPI2应用程序。 The IoC container is Castle Windsor. IoC容器是温莎城堡。 I have a method on my repository that I use to get some details for a user from DB. 我的存储库中有一个方法,用于从数据库获取用户的一些详细信息。 Since I don't need every column, I thought I'd use projection. 由于我不需要每一列,所以我认为我应该使用投影。 The problem is that the generated SQL selects ALL the columns in my table. 问题在于生成的SQL选择了我表中的所有列。 Here's the DbContext 这是DbContext
public partial class SecurityContext : DbContext
{
public SecurityContext()
: base("name=SecurityContext")
{
}
public virtual DbSet<User> secUsers { get; set; }
}
Here's where the context is declared/initialized in the repository 这是在存储库中声明/初始化上下文的地方
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
}
and here's the method in the repository 这是存储库中的方法
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
};
}
Here's the output SQL. 这是输出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]
I guess I'm doing something wrong, but I can't figure out what. 我想我做错了,但我不知道该怎么办。 Any ideas will be appreciated. 任何想法将不胜感激。
EDIT: I just noticed something strange - in the generated SQL there's no WHERE clause, which means that all the rows are selected from the database, brought to the client, and filtered there. 编辑:我只是注意到一些奇怪的事情-在生成的SQL中没有WHERE子句,这意味着所有行都从数据库中选择,带到客户端并在那里进行过滤。 EDIT 2: the same SQL is produced by using the LINQ query syntax. 编辑2:使用LINQ查询语法产生相同的SQL。 EDIT 3: After writing a unit test where I instantiate the repository and service manually (instead of leaving it to CastleWindsor), the SQL produced when running the test has the WHERE clause. 编辑3:编写单元测试后,在其中手动实例化存储库和服务(而不是将其留给CastleWindsor),运行测试时生成的SQL具有WHERE子句。
If your context
is something that returns an IEnumerable<T>
(and not IQueryable<T>
) from the Set<T>
method, then that's your problem, because the expression: 如果您的context
是从Set<T>
方法返回IEnumerable<T>
(而不是IQueryable<T>
)的东西,那么这就是您的问题,因为表达式:
context.Set<User>
.Where(...)
.Select(...)
.SingleOrDefault()
...will read the whole table into memory, and then apply the Where
clause and the projection ( Select
). ...将整个表读入内存, 然后应用Where
子句和投影( Select
)。 So, you would expect SELECT * FROM table
behaviour. 因此,您会期望SELECT * FROM table
行为。
The DbContext
class implementation of Set<T>
returns a DbSet<T>
which does implement IQueryable<T>
, so that would be OK. Set<T>
的DbContext
类实现返回一个DbSet<T>
,它确实实现了IQueryable<T>
,这样就可以了。 But since it looks like you have a custom repository implementation, I'm suspicious about what else might be going on behind the scenes... 但是由于您似乎已经有了一个自定义的存储库实现,因此我对幕后发生的事情感到怀疑...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.