Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use ToQuery outside the DbContext? #18957

Closed
Neme12 opened this issue Nov 17, 2019 · 4 comments
Closed

How to use ToQuery outside the DbContext? #18957

Neme12 opened this issue Nov 17, 2019 · 4 comments
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported

Comments

@Neme12
Copy link

Neme12 commented Nov 17, 2019

In a DbContext's OnModelCreating method, I can use ToQuery to map an entity type to a LINQ query as opposed to a table:

public sealed class Record
{
    public int Id { get; set; }
    public string Value { get; set; }
}

public sealed class RecordData
{
    public string Value { get; set; }
}

public sealed class ApplicationDbContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<RecordData>().HasNoKey().ToQuery(() => Records.Select(r => new RecordData { Value = r.Value }));
    }

    public DbSet<Record> Records { get; set; }
    public DbSet<RecordData> RecordData { get; set; }
}

but in our project, we like to use IEntityTypeConfiguration classes to configure each entity type and then call ApplyConfiguration from inside the DbContext as opposed to having any configuration directly there.

My question is, how to define the query passed to ToQuery in such a configuration class outside of the DbContext?

public sealed class RecordDataConfiguration : IEntityTypeConfiguration<RecordData>
{
    public void Configure(EntityTypeBuilder<RecordData> builder)
    {
        builder.HasNoKey().ToQuery(/* what goes here? */);
    }
}

I would expect the lambda in ToQuery to take a DbContext as the parameter so that I could do something like this:

builder.HasNoKey().ToQuery(context => context.Set<Record>().Select(r => new RecordData { Value = r.Value }));

but I don't see that being the case and can't think of any way to get the DbContext or DbSet for a specific entity type here. Am I missing something? What's the correct way to do this?

@ajcvickers
Copy link
Member

ajcvickers commented Nov 19, 2019

@Neme12 I just tested this and it works for me.

public sealed class RecordDataConfiguration : IEntityTypeConfiguration<RecordData>
{
    private readonly DbContext _context;

    public RecordDataConfiguration(DbContext context)
    {
        _context = context;
    }

    public void Configure(EntityTypeBuilder<RecordData> builder)
    {
        builder.HasNoKey().ToQuery(() => _context.Set<Record>().Select(r => new RecordData { Value = r.Value }));
    }
}
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        new RecordDataConfiguration(this).Configure(modelBuilder.Entity<RecordData>());
    }

It's probably also worth noting that ToQuery is not an area we are currently happy with and we plan to make changes in 5.0. See #18903 and #17270

@ajcvickers ajcvickers added closed-no-further-action The issue is closed and no further action is planned. and removed type-enhancement area-query labels Nov 19, 2019
@smitpatel
Copy link
Member

If it works for you then it works for everyone.

@stevendarby
Copy link
Contributor

@ajcvickers due to model caching is there not a chance that will capture the initial context only?

@ajcvickers
Copy link
Member

@Snappyfoo I don't think so, no.

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported
Projects
None yet
Development

No branches or pull requests

4 participants