Matt
Matt

Reputation: 27016

Easier way to run Entity Framework Core queries in LinqPad with builtin Linq to SQL driver?

Note: This is an old question. With LinqPad 5 you had the limitations I've described below, because it isn't written in .NET Core. But now you can use the newer LinqPad 6 or 7, which fully supports Entity Framework Core including drivers for multiple database systems.


I want to analyze Entity Framework Core queries, which I copied from existing code into LinqPad like

UserQuery this_context;
void Main()
{
    this_context = this;
    var validationResult = (

        from ProjectInfo pi in this_context.GetAll<ProjectInfo>()
        join GeneralInformation gi in this_context.GetAll<GeneralInformation>() 
                                   on pi.Id equals gi.Id into gpi
        from gps in gpi.DefaultIfEmpty()

        select new { ... }).ToList();
}

I know, that Linqpad does not support .NET Core, so I have to tweak it a bit - for this purpose I have created an Extension method as follows:

public static class Ext
{
    public static  IEnumerable GetAll<T>(this UserQuery uq)
    where T: new()
    {
        return GetAll(uq, new T());
    }

    private static  IEnumerable GetAll<T>(this UserQuery uq, T a)
    {
        switch (a)
        {
            case ProjectInfo v:
                return uq.ProjectInfo.Select(s => s);
            case GeneralInformation v:
                return uq.GeneralInformation.Select(s => s);

            // ... many more cases like the above 

            default: // unknown type
                throw new TypeAccessException($"Unsupported type {a.GetType().FullName}");
        }
    }
    
}

The overloaded GetAll function is required to get the type - it just creates an empty new object and passes it in so that the switch statement can properly deduct the correct type and return the right query.

That works fine, but it is a lot of effort to put in every single type into the switch statement.

So my question is:

How can this be achieved in a smarter way, i.e. without having to specify every single entity type?

Upvotes: 0

Views: 823

Answers (1)

NetMage
NetMage

Reputation: 26926

LINQPad's UserQuery object seems to have a method that is exactly what you want:

public static class Ext {
    public static IEnumerable GetAll<T>(this UserQuery uq) =>uq.GetTable(typeof(T));
}

I believe you could stay type safe with:

public static IQueryable<T> GetAll<T>(this UserQuery uq) => (IQueryable<T>)uq.GetTable(typeof(T));

Using your original IEnumerable version causes all the tables to be loaded into memory one by one and then the LINQ executed on the objects. Using IQueryable<T> translates the query to SQL - this may not be desirable in the cases where LINQ to SQL and EF differ in translation (for no good reason), but I could see issues with EF specific capabilities (e.g. Include and DbFunctions, though I have written empty Include extension methods to hide that some).

If the IQueryable version doesn't work, an ITable<> version may:

public static ITable<T> GetAll<T>(this UserQuery uq) where T : class => (ITable<T>)uq.GetTable(typeof(T));

Upvotes: 1

Related Questions