我正在转换ado.net代码以使用EF。在我的ado.net代码中,我设置了dataReader.FetchSize = command.RowSize * 1000
,这显着提高了默认提取大小的性能。
当我将我的代码转换为EF时,性能与ado.net代码相当,我没有指定获取大小,即它对大型记录的速度非常慢。
我可以用任何方式指定用于在EF中检索记录的获取大小吗?
答案 0 :(得分:2)
使用Entity Framework时,可以在注册表或.NET配置文件中设置ODP.NET FetchSize。这将在所有ODP.NET实例(在注册表的情况下)或整个应用程序(在app / web.config的情况下)标准化FetchSize。
http://docs.oracle.com/cd/E48297_01/doc/win.121/e41125/featConfig.htm
Christian Shay
的Oracle
答案 1 :(得分:0)
我遇到了类似的问题,但不想更改整体FetchSize,而是想更改每个查询的FetchSize。
这是我想出的解决方案,也许这对某人有帮助。
它基本上使用CallContext
来将参数传递给DbInterceptor
。拦截器将覆盖查询命令上所需的属性。
线程安全,支持嵌套作用域。
这也可以用于修改通过Entity Framework查询针对定义的范围执行的命令的其他属性。
用法:
using (var context = new MyDbContext())
{
using (new OracleCommandContext(fetchSize: 1024 * 128))
{
// your query here
}
}
要覆盖的属性:
public class OracleCommandProperties
{
public long FetchSize { get; set; } = 524288; // oracle default value
}
通话上下文:
public class OracleCommandContext : IDisposable
{
private static readonly object sync = new object();
private readonly OracleCommandProperties previousCommandProperties;
private bool isDisposed;
static OracleCommandContext()
{
DbInterception.Add(new OracleCommandInterceptor());
}
public OracleCommandContext(long fetchSize)
{
lock (sync)
{
var commandProperties = new OracleCommandProperties();
if (TryGetProperties(out var previousProperties))
{
// when using nested OracleCommandContext, escalate the properties
previousCommandProperties = previousProperties;
commandProperties.FetchSize = Math.Max(previousProperties.FetchSize, fetchSize);
}
else
{
commandProperties.FetchSize = fetchSize;
}
CallContext.LogicalSetData(nameof(OracleCommandProperties), commandProperties);
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~OracleCommandContext()
{
Dispose(false);
}
private void Dispose(bool disposing)
{
if (disposing)
{
if (!isDisposed)
{
lock (sync)
{
CallContext.LogicalSetData(nameof(OracleCommandProperties), previousCommandProperties);
}
isDisposed = true;
}
}
}
public static bool TryGetProperties(out OracleCommandProperties properties)
{
lock(sync)
{
if (CallContext.LogicalGetData(nameof(OracleCommandProperties)) is OracleCommandProperties oracleReaderProperties)
{
properties = oracleReaderProperties;
return true;
}
properties = null;
return false;
}
}
}
拦截器正在执行实际工作:
public class OracleCommandInterceptor : IDbCommandInterceptor
{
public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
}
public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
AdjustCommand(command);
}
public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
}
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
AdjustCommand(command);
}
public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
}
public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
AdjustCommand(command);
}
private static void AdjustCommand(DbCommand command)
{
if (command is OracleCommand oracleCommand)
{
if (OracleCommandContext.TryGetProperties(out var properties))
{
oracleCommand.FetchSize = properties.FetchSize;
}
}
}
}