2014-09-17 4 views
0

Моя таблица выглядит так (псевдо-код): CREATE TABLE DOCUMENT_LOCATOR (document_id VARCHAR2 (6) первичный ключ)Как искать таблицу Oracle с ключом строки с помощью Entity Framework 5 и ODP.NET Managed Provider

При использовании последней ODP.NET Managed Driver v121.1.2 загруженный через NuGet следующие команды Entity Framework не используйте индекс:

context.DOCUMENT_LOCATOR.Find("ABC123"); 
context.DOCUMENT_LOCATOR.Find(EntityFunctions.AsNonUnicode("ABC123")); 
context.DOCUMENT_LOCATOR.FirstOrDefault(i => i.DOCUMENT_ID == "ABC123"); 

следующая команда не использовать индекс:

context.DOCUMENT_LOCATOR.FirstOrDefault(i => i.DOCUMENT_ID == EntityFunctions.AsNonUnicode("ABC123")); 

К сожалению, UPDATE и DELETE не используют индекс, поэтому они в основном делают EF/Oracle бесполезными для больших таблиц. Кто-нибудь понял, как обойти это?

ответ

0

После достаточного количества поиска я нашел very nice solution. Он устанавливает все строковые свойства всех объектов в IsUnicode (false). Для того, чтобы использовать его, вы просто добавить одну строку в метод OnModelCreating вашего класса DbContext:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Configurations.Add(new ASSUMED_NAME_FILESMap()); 
     modelBuilder.Configurations.Add(new ASSUMED_NAME_FILENAME_ONLYMap()); 
     modelBuilder.Configurations.Add(new DOCUMENT_LOCATORMap()); 
     modelBuilder.Configurations.Add(new IMS_IMAGE_TABLEMap()); 

     modelBuilder.DisableUnicodeForAllEntityStrings(this); 
    } 

Как вы можете видеть, я изменил код, чтобы быть продолжением. Вот мой адаптированный код:

public static class DbModelBuilderExtensions 
{ 
    /// <summary> 
    /// Disables unicode for all string properties on entities in the given context. 
    /// MUST BE CALLED AFTER modelBuilder.Configurations.Add(map) CALLS. 
    /// </summary> 
    /// <remarks> 
    /// Adapted from http://www.johncoder.com/Post/EFCodeFirstDisableUnicodeforallStringProperties 
    /// </remarks> 
    public static void DisableUnicodeForAllEntityStrings(this DbModelBuilder builder, DbContext context) 
    { 
     // Get all IDbSet<> properties from the context 
     var entityTypes = from property in context.GetType().GetProperties() 
          where property.PropertyType.ImplementsInterface(typeof(IDbSet<>)) 
          let entityType = property.PropertyType.GetGenericArguments()[0] 
          select entityType; 

     // Disable Unicode support for each table 
     foreach (var entityType in entityTypes) 
      DisableUnicodeForEntityStrings(builder, entityType); 
    } 
    private static void DisableUnicodeForEntityStrings(DbModelBuilder modelBuilder, Type entityType) 
    { 
     // Get all string properties with setters 
     var stringProperties = from property in entityType.GetProperties() 
           where property.PropertyType == typeof(string) 
            && property.CanWrite 
           select property; 

     // Each table field must be varchar for now, 
     // so take the string property & call IsUnicode(false). 
     foreach (var property in stringProperties) 
     { 
      // Don't remove this line. 
      // Lambda might not work without it. 
      PropertyInfo prop = property; 

      // Create the correct expression type, 
      // should be Expression<Func<TModel, string>> 
      var exprType = typeof(Expression<>) 
       .MakeGenericType(typeof(Func<,>) 
       .MakeGenericType(prop.ReflectedType, typeof(string))); 

      // Find and execute the Entity() method, 
      // using TModel generic parameter 
      var obj = modelBuilder.GetType() 
       .GetMethod("Entity") 
       .MakeGenericMethod(prop.ReflectedType) 
       .Invoke(modelBuilder, null); 

      // Runtime Lambda expression to represent 
      // something like Property(p => p.Suffix) 
      ParameterExpression pe = Expression.Parameter(prop.ReflectedType, "p"); 
      var expression = Expression.Lambda(Expression.Property(pe, prop.Name), pe); 

      // Find the Property method that takes an expression as a parameter 
      // and then invoke it using the expression that was just built 
      var p = obj.GetType() 
       .GetMethod("Property", new[] { exprType }) 
       .Invoke(obj, new[] { expression }); 

      // If all goes well, we'll have a StringPropertyConfiguration. 
      var propertyConfig = p as StringPropertyConfiguration; 
      if (propertyConfig != null) 
       propertyConfig.IsUnicode(false); 
     } 
    } 
    public static bool ImplementsInterface(this Type value, Type interfaceType) 
    { 
     return value.GetInterface(interfaceType.FullName) != null; 
    } 
} 
Смежные вопросы