gpt4 book ai didi

c# - 使用继承的自定义 IDataReader 从 IDbCommand 读取

转载 作者:可可西里 更新时间:2023-11-01 09:11:38 30 4
gpt4 key购买 nike

我已经让一个自定义类继承IDataReader并且已经成功使用自定义类实现自定义 ServerWriter sqlBulkCopy,该自定义类使用 C# 对象而不是 DataTable

正如我所怀疑的那样,事实证明这是一种更有效的方法。

现在我正在尝试阅读,但我遇到了一些问题

这是IDataReader:

// get Server Data Table Object IDataReader
public class GetSDTOIDataReaderM : IDataReader
{
//private IEnumerator<MyTestObject> enumerator = null;

public MySqlDbTableObject.Raw.SqlDbTableM propSqlTbl { get; set; }

// implementing relevant GetValue(), filedCount() and Read()
// this is how I did with WriteToServer
public bool Read()
{
return ++this.ReaderRowsCount < this.propSqlTbl.Table.ElementAt(0).Row.Count;
}
}

对象被精确映射为它对应的 SqlTable。

在我的自定义 IDataReader 上将 SqlCommand 设置为 ExecuteReader() 不起作用,所以我尝试了IDbCommand 然后它确实编译了,但仍然在尝试读取时我得到一个错误:

Unable to cast object of type 'System.Data.SqlClient.SqlDataReader' to type 'GetSDTOIDataReaderM'

this.propComunicator.AsGetSDTOCom().SqlCmd.Connection.Open();
//this is the line of the error
using (this.propComunicator.AsGetSDTOCom().SDTOIDataReader = (Raw.Comunicator.Raw.GetSDTOIDataReaderM)this.propComunicator.AsGetSDTOCom().SqlCmd.ExecuteReader())
{

}

写入服务器时它确实有效,我如何使用 Read 正确实现它?

更新

关于我的模块的更多信息

public class TransManSF
{
public enum CommunicatorTypeS { Reader, Adapter, GetSDTOReaderA, SqlBcpyIDataReaderM };
public enum DbIntreactorTypeS { TableObject, TableRowObject, Sproc, SqlCmd };
public enum SqlCmdActionS { NotSet, SELECT, INSERT, UPDATE, DROP };
public enum SqlCmdStrSelModeS { Single, RecentEfected, count, All, Top10, Top100, Top1000 };
public enum SqlCmdStrSelOrderByS { NotSet = 0, Asc = 1, Desc = 2 };
public enum SqlCmdStrSetterModeS { Single, Multi};
public enum STDOTypeS { NotSet, ServerWriter, ServerTableGetter, ServerBiDerctional }
public enum SprocTypeS { Sproc, TvPSrpoc }
public enum TransExecActionTypeS { WriteToServer, GetTable }
}

public static TransMan.Raw.ComunicatorCLF.BulkCopyComSCL AsBulkCopyCom(this TransMan.Raw.ComunicatorCLF.ComunicatorM SelfCom)
{
return (TransMan.Raw.ComunicatorCLF.BulkCopyComSCL)SelfCom;
}

virtual public void ExecuteTransaction(AppMods.DataBase.TransManSF.TransExecActionTypeS parSelectedTransType, TransManSF.SqlCmdStrSelOrderByS parExecOrderByS, int OrderByOrdinal = 0)
{
if (parSelectedTransType == AppMods.DataBase.TransManSF.TransExecActionTypeS.WriteToServer)
using (this.propComunicator.AsBulkCopyCom().Conn)
{
this.propComunicator.AsBulkCopyCom().Conn.Open();
using (var IDRdrServerWriter = this.propComunicator.AsBulkCopyCom().ServerWriter)
{
var Eng = this.propExecuter.AsBulkCopyExec().Engine;
Eng.BulkCopyTimeout = 240;
Eng.WriteToServer(IDRdrServerWriter);

}
this.propComunicator.AsBulkCopyCom().Conn.Close();
}
else if (parSelectedTransType == AppMods.DataBase.TransManSF.TransExecActionTypeS.GetTable)
{
var DreaderCom = this.propComunicator.AsDReaderCom();
using (DreaderCom.SqlCmd.Connection)
{
DreaderCom.SqlCmd.Connection.Open();
using (DreaderCom.Driver = DreaderCom.SqlCmd.ExecuteReader())
{
if (DreaderCom.Driver.HasRows) while (DreaderCom.Driver.Read())
{
for (int i = 0; i < DreaderCom.Driver.FieldCount; i++)
{
var CurRdrColumn = DreaderCom.Driver.GetValue(i);
this.Table[i, 0] = CurRdrColumn;
}
}
}
DreaderCom.SqlCmd.Connection.Close();
}
}
}


public struct customComConfgBulkCopyA
{
public TransManSF.CommunicatorTypeS ComType;
public customComConfgBulkCopyA(TransManSF.CommunicatorTypeS ctrComType = TransManSF.CommunicatorTypeS.SqlBcpyIDataReaderM)
{
this.ComType = ctrComType;
}
}
public sealed class BulkCopyComSCL :CustomComA
{
public new Configurations.comunicator.customComConfgBulkCopyA Meta;
public SqlConnection Conn { get; set; }
public Raw.SqlBcpyIDataReaderM ServerWriter { get; set; }
}

public class SqlDbTableM : SqlDB1stTransA
{
virtual public DbSchema.Raw.TableDictionaryA TableDict { get; set; }
public virtual new TransMan.Raw.Configurations.SDB1stTransConfgF.SDTOMetaA Meta { get; set; }
virtual public Raw.ColumnSetsCollM Table { get; set; }
public override TransMan.Raw.ComunicatorCLF.ComunicatorM propComunicator
{
get
{
return base.propComunicator;
}
set
{
base.propComunicator = value;
}
}
public override TransMan.Raw.Executers.ExecuterM propExecuter
{
get
{
return base.propExecuter;
}
set
{
base.propExecuter = value;
}
}
public SqlDbTableM(TransManSF.STDOTypeS ctrTransType)
: base(TransManSF.DbIntreactorTypeS.TableObject) { }
}

public sealed class GetSDTOComSCL : CustomComA
{
public new Configurations.comunicator.customComConfgGetSDTOReaderA Meta;
public new IDbCommand SqlCmd;
public Raw.GetSDTOIDataReaderM SDTOIDataReader { get; set; }
}

最佳答案

简答:您不能更改 SqlCommand.ExecuteReader() 返回的类型.

它将始终是 SqlDataReader 的一个实例.

各种解决方案:

1 在对您有意义的地方包装内容。

走极端就自己写IDbProviderFactory包裹着 SqlConnection有自己的连接、命令和数据读取器类。

例如,这就是 Miniprofiler 用来检测所有 SQL 请求并收集执行时间、行数等的工作。Source code

或者你可以用某种扩展方法只包装阅读器,像这样:sqlCmd.ExecuteReader().AsMyReader() .什么AsMyReader()会做的是返回自定义 IDataReader做你的事情并委托(delegate)给实际的SqlDataReader .

2 使用现有的帮助程序库

我不太确定您在阅读内容时想要达到什么目的,但在这个领域存在不错的库。无需提出自己的解决方案。

FastMember ( Nuget ) 允许创建 IDataReader任何IEnumerable<T>周围的接口(interface)或 DataTable .它可以很容易地用作 SqlBulkCopy 的种子。轻松插入最大数据。将性能转化为 SQL Server 表。

此外,为了简化 SQL 查询的执行和解析其结果,Dapper太棒了。

关于c# - 使用继承的自定义 IDataReader 从 IDbCommand 读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33986901/

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