2015-12-07 2 views
6

Я поддерживаю приложение ASP.NET WebAPI2 с базой данных Entity 6 и базой данных MSSQL. Контейнер IoC - замок Виндзор. У меня есть метод в моем репозитории, который я использую для получения некоторых сведений для пользователя из БД. Поскольку мне не нужен каждый столбец, я думал, что буду использовать проекцию. Проблема в том, что сгенерированный SQL выбирает ВСЕ столбцы в моей таблице. Вот DbContextПроекция Entity framework 6 генерирует SQL-эквивалент «Select *» и не производит предложение WHERE

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] 

Я думаю, что я делаю что-то неправильно, но я не могу понять, что. Любые идеи будут оценены.

EDIT: Я только что заметил что-то странное - в сгенерированном SQL нет предложения WHERE, а это означает, что все строки выбираются из базы данных, доставляются клиенту и фильтруются там. EDIT 2: тот же SQL создается с использованием синтаксиса запроса LINQ. РЕДАКТИРОВАТЬ 3: После написания модульного теста, когда я создаю экземпляр репозитория и службу вручную (вместо того, чтобы оставлять его в CastleWindsor), SQL, созданный при запуске теста, имеет предложение WHERE.

+0

В вашем контексте, как объявляются множества? У них есть 'public virtual' или просто' public' – GregoryHouseMD

+0

Почему 'context.Set ()', а не 'context.secUsers()'? – GregoryHouseMD

+0

@GregoryHouseMD, потому что в репозитории контекст передается как DbContext. Я попробовал перебросить его в SecurityContext, прежде чем отвечать на ваш комментарий, но это не произвело никакой разницы. – user2936023

ответ

2

Если ваш context является то, что возвращает IEnumerable<T> (а не IQueryable<T>) из метода Set<T>, то это ваша проблема, потому что выражение:

context.Set<User> 
.Where(...) 
.Select(...) 
.SingleOrDefault() 

... будет читать всю таблицу в памяти, и , затем применяют пункт Where и прогноз (Select). Итак, вы будет ожидать SELECT * FROM table поведение.

DbContext реализация класса Set<T> возвращает DbSet<T>, который реализует IQueryable<T>, так что все будет в порядке. Но поскольку похоже, что у вас есть пользовательская реализация репозитория, я с подозрением отношусь к тому, что еще может произойти за кулисами ...

Смежные вопросы