我的应用程序中有一个自定义的DbDataReader,它覆盖GetDateTime方法来更改DateTimeKind。
public class MyDbDataReader : BaseDbDataReader
{
private string _dbName;
public MyDbDataReader(string dbName, DbDataReader source) : base(source)
{
_dbName = dbName;
}
public override DateTime GetDateTime(int ordinal)
{
var tableName = base.GetSchemaTable().TableName; //this doesn't work
return DateTime.SpecifyKind(base.GetDateTime(ordinal), base.GetName(ordinal).EndsWith("UTC", StringComparison.OrdinalIgnoreCase) ? DateTimeKind.Utc : DateTimeKind.Local);
}
}这是我的BaseDbDataReader:
public abstract class BaseDbDataReader : DbDataReader
{
readonly DbDataReader source;
public BaseDbDataReader(DbDataReader source)
{
this.source = source;
}
...
public override DataTable GetSchemaTable() { return source.GetSchemaTable(); }
}此dbReader在我的自定义拦截器中使用:
public class MyInterceptor : DbCommandInterceptor
{
public override void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
base.ReaderExecuted(command, interceptionContext);
if (!command.Connection.Database.Equals("...") &&
!(interceptionContext.Result is MyDbDataReader) &&
interceptionContext.Result != null &&
interceptionContext.Exception == null)
{
interceptionContext.Result = new MyDbDataReader(command.Connection.Database, interceptionContext.Result);
}
}
}在这里,我想要的就是在GetDateTime方法中获得TableName。但是GetSchemaTable方法返回一个无法理解的结果,其中TableName属性等于"SchemaTable“。我在这里做错了什么,以及如何获得正确的表名(如"Users")。
注意:我不使用SqlCommand和SqlCommand.ExecuteReader来执行查询。我只使用dbSet。即dbContext.Users.Where(x => x.Id = 1).Single();
发布于 2021-09-22 16:06:33
TableName属性将始终返回"SchemaTable",因为它不能返回其他有意义的名称。
根据the link you found,每列的表名应该在架构表的BaseTableName列中返回。但是只有在指定了CommandBehavior.KeyInfo标志的情况下才会返回。
深入研究源代码,看起来您需要使用ReaderExecuting方法,并接管执行该命令的责任:
public override void ReaderExecuting(
DbCommand command,
DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
// Skip processing for a specific database:
if (command.Connection.Database.Equals("...")) return;
var commandBehavior = interceptionContext.CommandBehavior | CommandBehavior.KeyInfo;
try
{
var reader = command.ExecuteReader(commandBehavior);
var result = new MyDbDataReader(command.Connection.Database, reader);
interceptionContext.Result = result;
}
catch (Exception ex)
{
interceptionContext.Exception = ex;
}
}理论上,您应该能够从架构表中提取BaseTableName列:
public override DateTime GetDateTime(int ordinal)
{
var schemaTable = base.GetSchemaTable();
var tableName = schemaTable.Rows[ordinal].Field<string>("BaseTableName");
...
}https://stackoverflow.com/questions/69287238
复制相似问题