在实体框架中设置获取大小

时间:2014-02-18 18:10:09

标签: ado.net oracle11g entity-framework-5 odp.net ado.net-entity-data-model

我正在转换ado.net代码以使用EF。在我的ado.net代码中,我设置了dataReader.FetchSize = command.RowSize * 1000,这显着提高了默认提取大小的性能。 当我将我的代码转换为EF时,性能与ado.net代码相当,我没有指定获取大小,即它对大型记录的速度非常慢。

我可以用任何方式指定用于在EF中检索记录的获取大小吗?

2 个答案:

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