首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Entity Framework6中使用DbDataReader获取表名?

如何在Entity Framework6中使用DbDataReader获取表名?
EN

Stack Overflow用户
提问于 2021-09-22 15:30:06
回答 1查看 134关注 0票数 1

我的应用程序中有一个自定义的DbDataReader,它覆盖GetDateTime方法来更改DateTimeKind。

代码语言:javascript
复制
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:

代码语言:javascript
复制
public abstract class BaseDbDataReader : DbDataReader
{
    readonly DbDataReader source;
    public BaseDbDataReader(DbDataReader source)
    {
        this.source = source;
    }

    ...
    public override DataTable GetSchemaTable() { return source.GetSchemaTable(); }
}

此dbReader在我的自定义拦截器中使用:

代码语言:javascript
复制
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();

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-22 16:06:33

TableName属性将始终返回"SchemaTable",因为它不能返回其他有意义的名称。

根据the link you found,每列的表名应该在架构表的BaseTableName列中返回。但是只有在指定了CommandBehavior.KeyInfo标志的情况下才会返回。

深入研究源代码,看起来您需要使用ReaderExecuting方法,并接管执行该命令的责任:

代码语言:javascript
复制
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列:

代码语言:javascript
复制
public override DateTime GetDateTime(int ordinal)
{
    var schemaTable = base.GetSchemaTable();
    var tableName = schemaTable.Rows[ordinal].Field<string>("BaseTableName");
    ...
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69287238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档