How to make streams from BLOBs available in plain old C# objects when using SqlDataReader?

前端 未结 3 1464
小鲜肉
小鲜肉 2021-02-04 13:48

This is the scenario:

  • We store files, e.g. relatively large documents (10-300MB), in blobs in our MSSQL database.
  • We have a very small domain model so we
相关标签:
3条回答
  • 2021-02-04 14:08

    There's a bug; you are ignoring the user's args, and you should probably guard for -ve returned:

      public override int Read(byte[] buffer, int index, int count)
      {
         long returned = dataReader.GetBytes(0, currentPosition,
             buffer, 0, buffer.Length);
         currentPosition += returned;
         return Convert.ToInt32(returned);
      }
    

    should probably be:

      public override int Read(byte[] buffer, int index, int count)
      {
         long returned = dataReader.GetBytes(0, currentPosition,
             buffer, index, count);
         if(returned > 0) currentPosition += returned;
         return (int)returned;
      }
    

    (otherwise you are writing into the wrong part of the buffer)

    But generally looks good.

    0 讨论(0)
  • 2021-02-04 14:16

    Note that .net 4.5 now does this OOB - SqlDataReader.GetStream()

    http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.getstream(v=vs.110).aspx

    0 讨论(0)
  • 2021-02-04 14:27

    That's gorgeous! Thanks for this memory saver. Besides Marc's fix I modified the constructor to open connection and dispose in case the open or execute fails to reduce code/exception handling in caller. (Didn't know Dispose could be called from constructor). Constructor mod:

    try
    {
        this.command = command;     // store for disposal
    
        if (command.Connection.State != ConnectionState.Open)
            command.Connection.Open();
    
        dataReader = command.ExecuteReader(CommandBehavior.SequentialAccess);
        dataReader.Read();            
    }
    catch (Exception ex)
    {
        Dispose();
        throw;
    }
    
    0 讨论(0)
提交回复
热议问题