linq store select clause as function variable

asp.net-core-webapi c# entity-framework-core linq

Question

is there a way to store the select clause of a linq statement as a variable?

I have the following class and the select clause is repeated can I store it as a variable somehow so I don't need to repeat it?

 public class TractRepository : ITractRepository
    {
        private DataContext context;

        public TractRepository(DataContext ctx) => context = ctx;
        public async Task<IEnumerable<Tract>> GetAllAsync() => 
            await context.Tracts.Include(p => p.ContractType).Include(p => p.ContractSubType).OrderByDescending(p => p.Id)
            .Select(p => new Tract
            {
                Id = p.Id,
                Acreage = p.Acreage,
                Administrative = p.Administrative,
                ContractType = new ContractType
                {
                    Id = p.ContractType.Id,
                    ContractTypeName = p.ContractType.ContractTypeName
                },
                ContractSubType = new ContractSubType
                {
                    Id = p.ContractSubType.Id,
                    ContractSubTypeName = p.ContractSubType.ContractSubTypeName
                }
            })
            .ToListAsync();

        public async Task<Tract> GetByIdAsync(long id) =>
            await context.Tracts.Include(p => p.ContractType).Include(p => p.ContractSubType)
             .Select(p => new Tract
             {
                 Id = p.Id,
                 Acreage = p.Acreage,
                 Administrative = p.Administrative,
                 ContractType = new ContractType
                 {
                     Id = p.ContractType.Id,
                     ContractTypeName = p.ContractType.ContractTypeName
                 },
                 ContractSubType = new ContractSubType
                 {
                     Id = p.ContractSubType.Id,
                     ContractSubTypeName = p.ContractSubType.ContractSubTypeName
                 }
             }).FirstOrDefaultAsync(p => p.Id == id);

    }
1
1
3/21/2020 12:56:35 AM

Accepted Answer

You can extract the whole common IQueryable<T> to separate property/method. Since LINQ queries are not executed until enumerated (the so called deferred execution), it can be used as base for composing other queries, e.g.

private IQueryable<Tract> Query() => context.Tracts
    //.Include(p => p.ContractType)
    //.Include(p => p.ContractSubType)
    .Select(p => new Tract
    {
        Id = p.Id,
        Acreage = p.Acreage,
        Administrative = p.Administrative,
        ContractType = new ContractType
        {
            Id = p.ContractType.Id,
            ContractTypeName = p.ContractType.ContractTypeName
        },
        ContractSubType = new ContractSubType
        {
            Id = p.ContractSubType.Id,
            ContractSubTypeName = p.ContractSubType.ContractSubTypeName
        }
    });

(Includes are redundant (ignored) for projection (Select) queries)

then

public async Task<IEnumerable<Tract>> GetAllAsync() => 
    await Query().OrderByDescending(p => p.Id).ToListAsync();

and

public async Task<Tract> GetByIdAsync(long id) =>
    await Query().FirstOrDefaultAsync(p => p.Id == id);
3
3/21/2020 3:12:25 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow