Tija
Tija

Reputation: 1737

How do you loop through all tables in a database context and query data

I need to run a query on all tables in my database context. I believe you can loop through the context tabes by doing

foreach (var entityType in context.Model.GetEntityTypes()) {

}

However I don't see a way to run linq queries on the entityType. Is there a way to do that.

Upvotes: 0

Views: 3607

Answers (2)

Tija
Tija

Reputation: 1737

I was able to get this code working:

PropertyInfo[] properties = context.GetType().GetProperties();
                foreach (PropertyInfo property in properties) {
                    var prop = context.GetType().GetProperty(property.Name).GetValue(context, null);
                    var table = prop as IEnumerable<BaseDbModel>;
                    if(table != null) {
                        var row = table.Select(a => a.createdDttm).FirstOrDefault();
                    }
                } 

Upvotes: 2

Travis J
Travis J

Reputation: 82287

Assuming that your code returns a set of types which correlates to entries in the DbSet<T> definitions,

i.e. I am assuming

IEnumerable<Type> entityTypes = context.Model.GetEntityTypes();

You could set up a method which could be called with that type, and simply use FirstOrDefault on its DbSet.

I am not sure what the exact scope of your area is, so some of this will assume that you need to adjust to fit into your architecture.

public class ThisClassReference
{

    // It wasn't provided, so this is just to show the containing method area,
    // and also provide reference to the current executing object instance,
    // which we will need to reference below
    public void YourExecutingMethod()
    {
        // Iterate through the set of entity types
        foreach (var entityType in context.Model.GetEntityTypes()) {

            // We need the class reference to construct the method call
            Type ThisClassReference = typeof(ThisClassReference);

            // We need the name of generic method to call using the class reference
            MethodInfo mi = ThisClassReference.GetMethod("FirstOrDefaultGeneric", BindingFlags.Instance | BindingFlags.NonPublic);

            // This creates a callable MethodInfo with our generic type
            MethodInfo miConstructed = mi.MakeGenericMethod(entityType);

            // This calls the method with the generic type using Invoke
            miConstructed.Invoke(this, null);
        }
    }

    // Once called use the generic type to access the first result in the DbSet from your context.
    private void FirstOrDefaultGeneric<T>()
    {
        var unUsed = context.Set<T>.FirstOrDefault();
    }

}

Bonus points for figuring out how to convert these calls to asynchronous ones and save yourself probably 40ms per type.

Upvotes: 3

Related Questions