Sto mantenendo un'applicazione Web.API2 ASP.NET con Entity framework 6 e il database del server MSSQL. Il container IoC è Castle Windsor. Ho un metodo sul mio repository che uso per ottenere alcuni dettagli per un utente dal DB. Dal momento che non ho bisogno di ogni colonna, ho pensato di usare la proiezione. Il problema è che l'SQL generato seleziona TUTTE le colonne nella mia tabella. Ecco il DbContextEntity framework 6 projection genera SQL equivalente a "Select *" e non produce WHERE clausola
public partial class SecurityContext : DbContext
{
public SecurityContext()
: base("name=SecurityContext")
{
}
public virtual DbSet<User> secUsers { get; set; }
}
Ecco dove il contesto è dichiarata/inizializzato nel 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
}
ed ecco il metodo nel 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
};
}
Ecco l'SQL uscita.
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]
Immagino di fare qualcosa di sbagliato, ma non riesco a capire cosa. Qualsiasi idea sarà apprezzata.
EDIT: Ho appena notato qualcosa di strano - nell'SQL generato non c'è alcuna clausola WHERE, il che significa che tutte le righe vengono selezionate dal database, portate al client e filtrate lì. EDIT 2: lo stesso SQL viene prodotto utilizzando la sintassi della query LINQ. EDIT 3: Dopo aver scritto un test unitario in cui istanzio il repository e il servizio manualmente (invece di lasciarlo a CastleWindsor), l'SQL prodotto durante l'esecuzione del test ha la clausola WHERE.
Nel tuo contesto, come vengono dichiarati i set? Hanno 'public virtual' o solo' public' – GregoryHouseMD
Perché 'context.Set()' e non 'context.secUsers()'? –
GregoryHouseMD
@GregoryHouseMD perché nel repository, il contesto viene passato come DbContext. Ho provato a trasmettere a SecurityContext prima di rispondere al tuo commento, ma non ha prodotto alcuna differenza. – user2936023