2015-11-29 15 views
10

Tôi đã tạo lớp kế thừa tùy chỉnh IDataReader và đã thực hiện thành công triển khai Máy chủ tùy chỉnh sqlBulkCopy với lớp tùy chỉnh sử dụng đối tượng C# thay vì DataTable.đọc từ IDbCommand bằng cách sử dụng tùy chỉnh kế thừa IDataReader

Điều đó được chứng minh là một cách tiếp cận hiệu quả hơn như tôi nghi ngờ.

Bây giờ tôi đang cố gắng để Read và tôi có một số vấn đề

Đây là 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; 
    } 
} 

Đối tượng được ánh xạ chính xác như SqlTable tương ứng của nó.

thiết lập một SqlCommand để ExecuteReader() trên tùy chỉnh của tôi IDataReader đã không làm việc vì vậy tôi đã thử với IDbCommand mà sau đó nó đã biên dịch, nhưng vẫn còn khi cố gắng đọc tôi nhận được một lỗi:

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()) 
{ 

} 

Khi ghi vào máy chủ nó đã hoạt động, làm cách nào để triển khai chính xác với Read?

CẬP NHẬT

nhiều hơn một chút về module của tôi

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; } 
} 
+0

PropComunicator.AsGetSDTOCom() trở lại là gì? Đây có phải là lớp học mà bạn có thể tham gia không? – RePierre

+0

@RePierre có chắc tôi sẽ thêm bản cập nhật 5 phút –

+0

@RePierre Nếu cần thêm thông tin, tôi sẽ vui lòng giải thích và chia sẻ xin lỗi mất 25 phút –

Trả lời

6

Câu trả lời ngắn: bạn không thể thay đổi kiểu trả về bởi SqlCommand.ExecuteReader().

Nó sẽ luôn là một phiên bản của SqlDataReader.

Các giải pháp khác nhau:

1 Làm mọi thứ hợp lý với bạn.

Nếu bạn đi đến cùng cực, hãy viết IDbProviderFactory của riêng bạn để kết thúc một số SqlConnection với kết nối, lệnh và lớp bộ dữ liệu của riêng nó.

Ví dụ, đó là những gì Miniprofiler nào để công cụ tất cả các yêu cầu SQL và thu thập thời gian thực hiện, số lượng hàng, vv Source code

Hoặc bạn có thể quấn chỉ người đọc với một số loại phương pháp khuyến nông, như vậy: sqlCmd.ExecuteReader().AsMyReader() . Những gì AsMyReader() sẽ làm là trả lại một tùy chỉnh IDataReader mà công cụ của bạn và đại biểu thực tế SqlDataReader.

thư viện helper

2 Sử dụng hiện

Tôi không chắc chắn chính xác những gì bạn đang cố gắng để đạt được khi đọc thứ, nhưng có tồn tại thư viện tốt trong không gian này. Không cần phải đưa ra các giải pháp của riêng bạn.

FastMember (Nuget) cho phép tạo các giao diện IDataReader xung quanh bất kỳ IEnumerable<T> hoặc DataTable nào. Nó được thực hiện để dễ dàng sử dụng như một hạt giống để SqlBulkCopy để dễ dàng chèn dữ liệu với tối đa. hiệu suất vào một bảng SQL Server.

Ngoài ra, để dễ dàng thực hiện truy vấn SQL và phân tích kết quả của chúng, Dapper thật tuyệt vời.

+0

nhìn vào liên kết đầu tiên tùy chỉnh 'DbCommand' là sự khởi đầu của một lõi của một giải pháp? nếu tôi sẽ sử dụng điều này như là lệnh sẽ làm cho cuộc sống dễ dàng hơn trên IDataReader' tùy chỉnh? 'public class ProfiledDbCommand: DbCommand, ICloneable' –

+0

Không, sự khởi đầu của mọi thứ là' DbProviderFactory'. Nó tạo ra 'DbConnection' của riêng nó, tạo ra' DbCommand' của riêng nó, tạo ra 'DbDataReader' của riêng mình. – jods

+0

ok vì vậy tôi sẽ tiếp tục điều tra từ nguồn 'DbProviderFactory' cảm ơn rất nhiều ngay bây giờ! –

Các vấn đề liên quan