Ich führe eine ASP.NET WebAPI2-Anwendung mit Entity-Framework 6 und MSSQL-Server-Datenbank. Der IoC-Container ist Castle Windsor. Ich habe eine Methode in meinem Repository, die ich verwende, um einige Details für einen Benutzer aus der DB zu erhalten. Da ich nicht jede Spalte brauche, dachte ich, ich würde Projektion verwenden. Das Problem besteht darin, dass das generierte SQL ALLE Spalten in meiner Tabelle auswählt. Hier ist der DbContextEntity Framework 6 Projektion generiert SQL entspricht "Select *" und erzeugt keine WHERE-Klausel
public partial class SecurityContext : DbContext
{
public SecurityContext()
: base("name=SecurityContext")
{
}
public virtual DbSet<User> secUsers { get; set; }
}
Hier ist, wo der Kontext, in dem Repository deklariert/initialisiert
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
}
und hier ist das Verfahren im 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
};
}
Hier ist die Ausgabe von 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]
Ich denke, ich mache etwas falsch, aber ich kann nicht herausfinden, was. Irgendwelche Ideen werden geschätzt.
EDIT: Ich habe gerade etwas seltsam bemerkt - in der generierten SQL gibt es keine WHERE-Klausel, was bedeutet, dass alle Zeilen aus der Datenbank ausgewählt, zum Client gebracht und dort gefiltert werden. EDIT 2: das gleiche SQL wird mithilfe der LINQ-Abfragesyntax erstellt. EDIT 3: Nach dem Schreiben eines Komponententests, bei dem ich das Repository und den Dienst manuell instanziiere (anstatt es CastleWindsor zu überlassen), hat das beim Ausführen des Tests erzeugte SQL die WHERE-Klausel.
In Ihrem Kontext, wie sind die Sätze deklariert? Haben sie 'public virtual' oder nur' public'? – GregoryHouseMD
Warum 'context.Set()' und nicht 'context.secUsers()'? –
GregoryHouseMD
@GregoryHouseMD, weil der Kontext im Repository als DbContext übergeben wird. Ich habe versucht, es auf SecurityContext zu übertragen, bevor ich auf Ihren Kommentar antwortete, aber es ergab keinen Unterschied. – user2936023