2014-10-27 19 views
8

Điều gì sẽ xảy ra nếu tôi muốn truy cập vào một tính năng duy nhất cho RDBMS? Có cách nào để tiêm DB cụ thể SQL vào SQL được tạo ra bởi EF?Sự trừu tượng của Khung thực thể bị rò rỉ - chỉ cần một chút

Ví dụ, trong Oracle 12c bạn có thể thêm giá trị thời gian để DDL và DML (có rất nhiều loại, tôi sẽ sử dụng ví dụ chỉ đơn giản ở đây):

này có thể độc đáo mô hình trong C#:

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

Sau đó sử dụng với LINQ

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

Việc gia hạn .AsOfPeriodFor có thể là cái gì đó như thế này:

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; 
    } 
} 

Và tôi đoán DbContext có thể phản ánh trên thực thể của nó để thúc đẩy DDL lúc khởi tạo (tôi sẽ phải tìm hiểu thêm về điều này).

Kết quả trên được EF sẽ phát ra các lệnh SQL sau

DDL (tại thời điểm khởi tạo):

create table some_table 
    some_field varchar2(30) 

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

DML (tại thời điểm truy vấn):

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'; 

Câu hỏi của tôi : Có móc hoặc IInterfaces có sẵn để tiêm các cụm từ đặc biệt RDBMS vào SQL được tạo ra bởi EF không? Hoặc sẽ phải kết hôn ở trên với một nhà cung cấp Oracle DB tùy chỉnh? Đây là loại điều có thể và bạn có thể chỉ cho tôi một blog/cuốn sách/video/guru có thể cung cấp hướng dẫn?

+1

Không phải là nguồn mở EF? – Ben

+1

@Ben Tốt điểm - Tôi không nghĩ về điều đó. Nếu thất bại, tôi sẽ xem qua mã. Tôi đã hy vọng sẽ có những mô hình phổ biến, thực hành tốt nhất có ai đó có thể chỉ cho tôi. – biscuit314

+0

Vì truy vấn đơn giản là một IQueryable và bạn dường như biết các tùy chọn tại thời gian biên dịch, có vẻ như bạn có thể tiếp tục ngăn xếp các biến vị ngữ có điều kiện trên truy vấn ban đầu cho đến khi bạn sẵn sàng thực thi, đúng không? Trong trường hợp bạn cần thao tác dữ liệu khi chèn, cập nhật, xóa, bạn có thể thêm các trình kích hoạt được duy trì bởi EF và như là phương sách cuối cùng chỉ đơn giản là ánh xạ thực thể vào một proc được lưu trữ. –

Trả lời

1

Không có cách nào, theo hiểu biết của tôi, để sửa đổi SQL được tạo bởi nhà cung cấp EF.

Tuy nhiên, đối với những trường hợp đặc biệt đó, bạn có thể chạy SQL trực tiếp.

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

Bạn chỉ cần đảm bảo rằng bất kỳ điều gì bạn trả lại đều khớp với hình dạng của SomeEntity.

0

Thực hiện một Interceptor: EF-Tutorial

Trông như thế này:

class EFCommandInterceptor: IDbCommandInterceptor 
     { 
      public void NonQueryExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext) 
      { 
       LogInfo("NonQueryExecuted", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText)); 
      } 

      public void NonQueryExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext) 
      { 
       LogInfo("NonQueryExecuting", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText)); 
      } 

      public void ReaderExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContextt<System.Data.Common.DbDataReader> interceptionContext) 
      { 
       LogInfo("ReaderExecuted", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText)); 
      } 

      public void ReaderExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext) 
      { 
       LogInfo("ReaderExecuting", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText)); 
      } 

      public void ScalarExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext) 
      { 
       LogInfo("ScalarExecuted", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText)); 
      } 

      public void ScalarExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext) 
      { 
       LogInfo("ScalarExecuting", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText)); 
      } 

      private void LogInfo(string command, string commandText) 
      { 
       Console.WriteLine("Intercepted on: {0} :- {1} ", command, commandText); 
      } 
     } 

Nhưng làm thế nào để có được các loại để có được những metadata tôi không biết bây giờ.

Các vấn đề liên quan