我的表是这样的(伪代码): CREATE TABLE DOCUMENT_LOCATOR(DOCUMENT_ID VARCHAR2(6)PRIMARY KEY)
使用通过NuGet下载的最新ODP.NET托管驱动程序v121.1.2时,以下实体框架命令不使用索引:
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 :(得分:0)
经过大量的搜索,我找到了very nice solution。它将所有实体的所有字符串属性设置为IsUnicode(false)。要使用它,只需在DbContext类的OnModelCreating方法中添加一行:
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;
}
}