Specification
Specification copied to clipboard
Can ignore properties in Select Specifications?
I've saw the docs about Select.
public class SitemapPageSpecification : Specification<Page, SitemapPageDto>
{
public SitemapPageSpecification()
{
_ = Query
.Where(e => !e.IsDeleted
&& !e.IsHiddenPage
&& e.Status == PageStatus.Published
&& e.PageTypeId != nameof(WebpageType.Post)
&& e.PageTypeId != nameof(WebpageType.PostCategory)
&& e.PageTypeId != nameof(WebpageType.Blog));
_ = Query
.Select(e => new SitemapPageDto
{
Path = e.NiceUrl,
LastModified = e.DateUpdated ?? e.DateCreated
});
}
}
But it seem does not work in my case.
Expected: Some unnecessary properties slow down the query. Can I remove them from the SQL query?
Hi @datnt97,
I think you're missing the methods that return TResult
in your repository implementation. Here is the built-in implementation.
I tried it. But it seems like it's not working as expected as well. Am I doing something wrong here?
Hey @datnt97
Here I created a full sample app for you. We're confident it works properly, it's battle-tested on production for a long time. Perhaps you should cross-check everything on your side once again. This is the generated SQL statement for the app.
SELECT [c].[Id], [c].[FirstName]
FROM [Customers] AS [c]
using Ardalis.Specification;
using Ardalis.Specification.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
await AppDbContext.SeedAsync();
using var dbContext = new AppDbContext();
var repo = new Repository<Customer>(dbContext);
var spec = new CustomerDtoSpec();
var result = await repo.ListAsync(spec);
Console.WriteLine(result.Count);
public interface IRepository<T> : IRepositoryBase<T> where T : class { }
public class Repository<T> : RepositoryBase<T> where T : class
{
public Repository(AppDbContext dbContext)
: base(dbContext) { }
}
public class CustomerDtoSpec : Specification<Customer, CustomerDto>
{
public CustomerDtoSpec()
{
Query.Select(x => new CustomerDto
{
Id = x.Id,
FirstName = x.FirstName
});
}
}
public class CustomerDto
{
public int Id { get; set; }
public string? FirstName { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
}
public class AppDbContext : DbContext
{
public DbSet<Customer> Customers => Set<Customer>();
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connectionString = "Data Source=(localdb)\\MSSQLLocalDb;Initial Catalog=SpecificationSelectDemo;Integrated Security=SSPI;Trusted_Connection=true";
optionsBuilder.UseSqlServer(connectionString).LogTo(Console.WriteLine);
}
public static async Task SeedAsync()
{
using var dbContext = new AppDbContext();
var customers = new List<Customer>()
{
new() { FirstName = "Customer1", LastName = "Customer1" },
new() { FirstName = "Customer2", LastName = "Customer2" },
new() { FirstName = "Customer3", LastName = "Customer3" },
};
await dbContext.Database.EnsureCreatedAsync();
dbContext.AddRange(customers);
await dbContext.SaveChangesAsync();
}
}
Thank you for your greatest help!