Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Leaking Entity Framework's abstraction - just a little

What if I want access to a feature unique to the RDBMS? Is there a way to inject DB specific SQL into the SQL generated by EF?

For example, in Oracle 12c you can add temporal validity to DDL and DML (there is a lot of variety; I'll use only simple examples here):

This could be nicely modeled in C#:

[TemporalAxis("valid_time")]
public class SomeEntity
{
  public string SomeField { get; set; }
}

Then used with LINQ

var results = context.SomeEntities
                .Where(i => i.SomeField = "some_value")
                .AsOfPeriodFor("valid_time", dateVariable);

The .AsOfPeriodFor extension can be something like this:

public static class TemporalExtensions
{
    public static IEnumerable<TSource> AsOfPeriodFor<TSource>(this IEnumerable<TSource> source, 
        string temporalAxis, DateTime asOfDate)
    {
        // reflect on TSource to ensure it has the correct attribute/value (else degrade/throw)
        // do something to source that sets up EF to add the extra clause in the DML

        return source;
    }
}

And I guess the DbContext can reflect on its entities to drive the DDL at initialization time (I'll have to learn more about this).

The result of the above is EF will emit the following SQL

DDL (at initialize time):

create table some_table
  some_field varchar2(30)

  period for valid_time -- Need to inject this at DB Initialize time
);

DML (at query time):

select
  some_field
from 
  some_table
  as of period for valid_time to_timestamp('27-Oct-14') -- and this at query time
where
  some_field = 'some_value';

My question: Are there hooks or IInterfaces available to inject these RDBMS specialty phrases into the SQL generated by EF? Or will have to marry the above with a custom Oracle DB Provider? Is this type of thing possible and can you point me to a blog/book/video/guru that can provide guidance?

like image 753
biscuit314 Avatar asked Oct 27 '14 20:10

biscuit314


1 Answers

There is no way, to my knowledge, to modify the SQL that gets generated by an EF provider.

However, for those special cases, you can run SQL directly.

context.Database.SqlQuery<SomeEntity>("select * from SomeEntity " +
"some more custom sql here " +
"where somecomlumn = @p1", parameter1);

You just have to make sure whatever you return matches the shape of SomeEntity.

like image 168
Jason Gerard Avatar answered Nov 16 '22 03:11

Jason Gerard