Я знаю, что прошло с момента публикации, но я добавлю свой ответ, чтобы помочь кому-то другому. У меня были общие таблицы очереди SQL с разными именами таблиц. То есть схема одинакова для обеих таблиц. Я создал фреймворк, чтобы вы могли динамически опробовать таблицу по вашему выбору, указав имя, и именно поэтому мне нужно было обновить имя таблицы во время выполнения. В принципе, вы можете создать перехватчик для перехвата необработанных SQL-запросов из структуры сущностей и обновления имени таблицы оттуда.
public class MyInterceptor : IDbCommandInterceptor
{
private const string TableReplaceString = "[TheTableNameToReplace]";
private void ReplaceTableName(DbCommand command, IEnumerable<DbContext> contexts)
{
var myContext = contexts?.FirstOrDefault(x => x is MyContext) as MyContext;
if (myContext != null && command != null && command.CommandText.Contains(TableReplaceString))
{
command.CommandText = command.CommandText.Replace(TableReplaceString, $"[{myContext.NewTableName}]");
}
}
public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
ReplaceTableName(command, interceptionContext.DbContexts);
}
public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
ReplaceTableName(command, interceptionContext.DbContexts);
}
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
ReplaceTableName(command, interceptionContext.DbContexts);
}
public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
ReplaceTableName(command, interceptionContext.DbContexts);
}
public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
ReplaceTableName(command, interceptionContext.DbContexts);
}
public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
ReplaceTableName(command, interceptionContext.DbContexts);
}
}
Конечно, вам нужно получить новое имя таблицы откуда-то. Либо из конструктора, либо из сохраненного поля в вашем настраиваемом DBC-тексте, который вы можете захватить из interceptionContext.DbContexts.
Тогда вам просто нужно зарегистрировать перехватчик для вашего контекста.
public class MyContext : DBContext
{
public readonly string NewTableName;
public MyContext(string connectionString, string newTableName)
: base(connectionString)
{
NewTableName = newTableName;
// Set interceptor
DbInterception.Add(new QueueMessageInterceptor());
}
}
UPDATE: Я обнаружил, что если добавить перехватчик в конструкторе выше вызвать утечку памяти. DotMemory об этом не говорит. Убедитесь, что вы добавили перехватчик в статический конструктор.
public class MyContext : DBContext
{
public readonly string NewTableName;
static MyContext()
{
// Set interceptor only in static constructor
DbInterception.Add(new QueueMessageInterceptor());
}
public MyContext(string connectionString, string newTableName)
: base(connectionString)
{
NewTableName = newTableName;
}
}
кажется очень странным требованием; можете ли вы подробнее объяснить, что вы пытаетесь выполнить, изменив имя таблицы? – Claies
История моего req такова: таблица db хранит много миллионов записей. Чтобы гарантировать приемлемую повседневную производительность, я хочу провести «последние» записи в основной таблице (около 1-2 миллионов) и переместить по расписанию все «старые» записи (> 100 миллионов в общей сложности) во вторичную идентичную таблицу. Пользователь может с помощью переключателя уровня приложения использовать режим «исторические данные» и переключиться на вторичную таблицу, используя точно такую же модель, объекты и запросы – GrMikeD
Я не уверен, возможно ли это с помощью первой модели БД, но я знаю это возможно с использованием кода First. Вы можете узнать больше о моих промах в моем ответе на аналогичный вопрос (используя Code First) [здесь] (http://stackoverflow.com/questions/27032292/entity-framework-code-first-returning-same-data-for -Разные столы, отображенные к s/27050034 # 27050034). –