---------------- describing why this is not a duplicate -------------
EDIT: This is different than the question marked as a duplicate because I am not trying to re-query the list that is returned (and further refine it). E.G. If I change the ClientProviderAccountRep.GetByProviderID method from a .Where to a .First(), I would still expect the following to be optimized with an EXISTS:
If I change the GetByProviderID to this:
public ClientProviderAccount GetByProviderID(Guid providerID)
{
return Db.ClientProviderAccounts.First(cpa => cpa.IsActive && cpa.ProviderID == providerID);
}
Then use that method here:
var clientProviderAccount = ClientProviderAccountRep.GetByProviderID(providerId);
var schedulesExist = clientProvider.Schedules.Any();
Our application uses entity framework 6.1. The entity can have a large collection of children (schedules). We have a method that is transforming the EF entity into a viewmodel entity. For the purpose of the ViewModel, it does not need all the schedules. It just needs to know if one exists. I expected using .Any() would not get the query and create the whole list of schedules.
var lst = ClientProviderAccountRep.GetByProviderID(providerID).Select(x => new ClientProviderAccountVM
{
ClientProviderAccountID = x.ClientProviderAccountID,
ClientID = x.ClientID,
ClientName = x.Client.Name,
ProviderID = x.ProviderID,
ProviderName = x.Provider.Name,
Name = x.Name,
LoginID = x.LoginID,
Password = x.Password,
StartRecordNumber = x.StartRecordNumber,
IsActive = x.IsActive,
SchedulesExist = x.Schedules.Any(s => s.IsActive == true)
})
The problem line is:
SchedulesExist = x.Schedules.Any(s => s.IsActive == true)
I would have expected a really quick EXISTS call, but it is getting all the schedule objects first.
Things I have tried:
foreachinstead of the.GetByProviderID(providerID).Select(x.
then creating ViewModel with the object initializer syntax.- in a loop, creating a new ViewModel and setting each property explicitly.
I am pretty sure I tried other permutations, but have not been successful.
here is the generated DbContext:
public partial class AppLogDb : DbContext
{
public AppLogDb()
: base("name=AppLogDb")
{
this.Configuration.LazyLoadingEnabled = false;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet ApplicationLogs { get; set; }
public virtual DbSet AuditLogs { get; set; }
public virtual DbSet LogDetails { get; set; }
public virtual DbSet LoginLogs { get; set; }
}
Here is the GetByProviderID method. The Db is the database context. I know there is a too list, but I don' think that is it because it is still lazy loading the schedules after returning from this method. The ToLis(), just realizes the top parent object (I think).
public IEnumerable GetByProviderID(Guid providerID)
{
var clientProviderAccount = Db.ClientProviderAccounts
.Where(cpa => cpa.IsActive && cpa.ProviderID == providerID)
.ToList();
return clientProviderAccount.OrderBy(cpa => cpa.Name);
No comments:
Post a Comment