gpt4 book ai didi

entity-framework - 在运行时更改表名

转载 作者:行者123 更新时间:2023-12-03 14:19:24 27 4
gpt4 key购买 nike

假设我有一个名为 Employee 的 db 表和一个相应的 EF 6.0 db-first 模型。

获取表 Employee 的所有行是通过查询完成的:context.Employees.ToList()
是否可以在运行时和按需将数据库表名重定向到 Test1,同时使用相同的对象名和查询?

也许是 EF 6.0 拦截器使用的案例?

最佳答案

我知道距离原始帖子已经有一段时间了,但我会添加我的答案以帮助其他人。我有具有不同表名的通用 SQL 队列表。 IE。两个表的架构完全相同。我创建了一个框架,以便您可以通过提供名称来动态轮询您选择的表,这就是我需要在运行时更新表名称的原因。基本上,您可以创建一个拦截器来拦截来自 Entity Framework 的原始 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);
}
}

当然,您必须从某个地方获取新表名。从构造函数或自定义 DBContext 中存储的字段,您可以从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 MyInterceptor());
}
}

更新:
我发现如果在上面的构造函数中添加拦截器会导致内存泄漏。 DotMemory 不会告诉你这个。确保在静态构造函数中添加拦截器。
public class MyContext : DBContext
{
public readonly string NewTableName;

static MyContext()
{
// Set interceptor only in static constructor
DbInterception.Add(new MyInterceptor());
}

public MyContext(string connectionString, string newTableName)
: base(connectionString)
{
NewTableName = newTableName;
}
}

关于entity-framework - 在运行时更改表名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27259949/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com