그냥 재미있게하기 위해 아래에 클래스를 만들려고했습니다. 분명히 테스트하는 번거 로움이 될 것입니다.
왜 고통 스러울 지 설명하기 전에, 나는 당신에게 문제를 해결하기위한 변명을 할 것입니다. 학급에서 IDataReader
을 만들 경우 발신자에게 전달해야 할 충분한 이유가 없습니다. 그들로부터 데이터를 읽고 인을 호출자에게 전달할 수 있습니다. 발신자에게 실제 데이터가 아닌 독자가 필요한 이유가 있습니까? datareader를 열고 닫는 것은 과정에서 너무 많은 손을 가지지 않고 성취하고자하는 것입니다. 그래서 당신이 그것을 열고, 필요한 것을 얻은 다음, 그것을 닫으면 이상적입니다.
IDataReader
내에서 한 결과 집합에서 다음 집합으로 넘어갈 때 일반적으로 한 번의 호출을 수행하기 때문에 결과 집합을 따르는 것이 더 쉽습니다. 방금 XYZ 프로 시저를 호출했습니다. 두 개의 결과 집합을 반환하므로 두 결과 집합을 모두 확인해야합니다. 인위적으로 결합 된 작은 것들이 많을 때 특히 결과 세트가 많고 많은 IDataReader
을 처리하고 싶지 않습니다. 많은 결과 집합을 추적하고 서로 다른 열이 포함되어 있기 때문에 여러 가지 결과 집합을 읽는 방법을 전환해야합니다.
그리고 이러한 열린 연결의 문제도 있습니다. 일반적으로 독자와 작업을 마칠 때 연결을 끊습니다. 하지만 이제는 연결이 끊어 질 때 명확하지 않습니다. 어느 연결이 어떤 독자에게 속해 있는지 어떻게 알 수 있습니까? 다른 리더가 여전히 그것을 사용하는 동안 리더에 대한 연결을 닫으면 어떻게 될까요?
그래서 여기에 대략적인 모습이 있습니다. 나는 분명히 이것을 시험하지 않았다. NextResult
이 호출되어 현재 판독기 내에 다음 결과가없는 경우 어느 것이 현재인지 추적하고 다음 판독기로 진행되도록 처리해야합니다. 독자는 독자를 닫고 모두 처분해야합니다. 이것은 테스트 될 수 있지만 테스트는 단지 두통 일 뿐이며, 이는 종종 무언가를하지 말라는 좋은 경고입니다.
public class AggregateDataReader : IDataReader
{
private readonly Queue<IDataReader> _readers;
private IDataReader _current;
public AggregateDataReader(IEnumerable<IDataReader> readers)
{
_readers = new Queue<IDataReader>(readers);
}
private bool AdvanceToNextReader()
{
_current?.Dispose();
var moreReaders = _readers.Any();
if (moreReaders) _current = _readers.Dequeue();
return moreReaders;
}
public bool NextResult()
{
if (_current == null) return false;
if (_current.NextResult()) return true;
return AdvanceToNextReader();
}
public bool Read()
{
return _current.Read();
}
public void Dispose()
{
_current?.Dispose();
while (_readers.Any()) _readers.Dequeue().Dispose();
}
public string GetName(int i)
{
return _current.GetName(i);
}
... lots of these...
public byte GetByte(int i)
{
return _current.GetByte(i);
}
public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
{
return _currentGetBytes(i, fieldOffset, buffer, bufferoffset, length);
}
... etc...
public void Close()
{
_current?.Close();
while (_readers.Any()) _readers.Dequeue().Close();
}
... etc...
}
감사합니다. 나는 함정을 이해하고 그들을 조심할 것이다. 단지 이미 구축 된 것과 같은 솔루션이 있어야하는 복잡하지만 유효한 유스 케이스처럼 보입니다. –