Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to modify an IQueryable expression manually

I'm pretty certain I know the answer is no but as a last ditch attempt I thought I'd ask the question here.

I'm using EF code first to query a table in the usual fashion

_context.Set<Foo>().Where(f => f.Bar == 999);

which creates the following expression (I've just written this so it might be wrong).

{SELECT 
[Extent1].[Test] AS [Test], 
[Extent1].[Test2] AS [Test2], 
FROM [dbo].[Foo] AS [Extent1]
WHERE 19 = [Extent1].[Bar]}

Now, is it possible to manually modify this query to change the table name to, say, Foo10? (probably not)

Failing that, does anybody know of a way I can "late bind" the table name in code first?

You're probably wondering "Why the dirty hack?" As usual, this is a legacy issue with a database that's got some design issues and can't be changed.

Thanks in advance.

Ps. I'm aware that I could use Database.SqlQuery but would rather not.

like image 451
mat-mcloughlin Avatar asked Nov 05 '22 06:11

mat-mcloughlin


1 Answers

Why don't you use TPT inheritance on your model?

Similar to @Krizz's answer, but you avoid using dynamic LINQ.

Using your comment:

if a particular parameter has a value of 1 look in Foo1 if its 2 look in Foo2 and so on

So, you could do this:

var query = ctx
   .Foos
   .OfMyType(value)
   .Where(f => f.Bar == 999) // f.Bar is on the base/abstract entity.
   .ToList();

Where OfMyType is a custom extension method on IQueryable<T>:

public static IQueryable<T> OfMyType<T>(this IQueryable<T> source, string value)
{
   switch (value)
   {
      case "1":
         return source.OfType<Foo1>();
      case "2":
         return source.OfType<Foo2>();
      // etc, etc
   }
}

Most (if not all) of the properties will be on the abstract "Foo" entity, and you create derived entities for each of the tables, which each have their own backing table.

That way, "consuming" code (e.g the ones making the queries), need not care about the different tables/Foo's, they simply pass the "magic value" to your repository (hopefully your using one), then you can silently switch to the table you want.

Would that work?

like image 180
RPM1984 Avatar answered Nov 09 '22 12:11

RPM1984