SqlSugar/Src/Asp.NetCore2/MongoDb.Ado.data/MongoDbDataReader.cs

152 lines
5.6 KiB
C#
Raw Normal View History

2025-04-26 19:46:11 +08:00
using System;
using System.Collections.Generic;
using System.Data.Common;
using MongoDB.Driver;
using MongoDB.Bson;
using System.Data;
using System.Collections;
2025-05-02 14:30:13 +08:00
using System.Linq;
2025-05-05 14:26:49 +08:00
using MongoDB.Bson.Serialization;
2025-04-26 19:46:11 +08:00
namespace MongoDb.Ado.data
{
2025-05-02 11:39:41 +08:00
public class MongoDbBsonDocumentDataReader : DbDataReader
{
private readonly IEnumerator<BsonDocument> _enumerator;
private BsonDocument _current;
2025-05-05 14:26:49 +08:00
private IEnumerable<BsonDocument> _documents;
private BsonDocument _firstObj;
2025-05-02 11:39:41 +08:00
public MongoDbBsonDocumentDataReader(IEnumerable<BsonDocument> documents)
{
2025-05-02 14:54:14 +08:00
_enumerator = documents.GetEnumerator();
2025-05-05 14:26:49 +08:00
_documents = documents;
_firstObj=_documents.FirstOrDefault();
2025-05-02 11:39:41 +08:00
}
public override bool Read()
{
if (_enumerator.MoveNext())
{
_current = _enumerator.Current;
return true;
}
return false;
}
2025-05-05 14:26:49 +08:00
public override int FieldCount => _documents?.FirstOrDefault()?.Count()??0;
2025-05-02 11:39:41 +08:00
public override int Depth => throw new NotImplementedException();
public override bool HasRows => true;
public override bool IsClosed => false;
public override int RecordsAffected => -1;
public override bool NextResult() => false;
public override object this[int ordinal] => GetValue(ordinal);
public override object this[string name] => GetValue(GetOrdinal(name));
// 下面这些可以根据需要进一步实现或抛异常
public override bool GetBoolean(int ordinal) => (bool)GetValue(ordinal);
public override byte GetByte(int ordinal) => (byte)GetValue(ordinal);
public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length) => throw new NotSupportedException();
public override char GetChar(int ordinal) => (char)GetValue(ordinal);
public override long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length) => throw new NotSupportedException();
public override string GetDataTypeName(int ordinal) => GetFieldType(ordinal).Name;
public override DateTime GetDateTime(int ordinal) => (DateTime)GetValue(ordinal);
public override decimal GetDecimal(int ordinal) => (decimal)GetValue(ordinal);
public override double GetDouble(int ordinal) => (double)GetValue(ordinal);
2025-05-02 14:54:14 +08:00
public override Type GetFieldType(int ordinal)
{
2025-05-05 14:26:49 +08:00
var firstObj = _firstObj;
if(firstObj==null) return typeof(object);
var obj = firstObj.GetValue(ordinal);
if (obj is BsonObjectId)
{
return typeof(string);
}
2025-05-02 14:54:14 +08:00
if (obj == null) return typeof(object);
2025-05-05 14:26:49 +08:00
return BsonTypeMapper.MapToDotNetValue(obj).GetType();
2025-05-02 14:54:14 +08:00
}
2025-05-02 11:39:41 +08:00
public override float GetFloat(int ordinal) => (float)GetValue(ordinal);
public override Guid GetGuid(int ordinal) => (Guid)GetValue(ordinal);
public override short GetInt16(int ordinal) => (short)GetValue(ordinal);
public override int GetInt32(int ordinal) => (int)GetValue(ordinal);
public override long GetInt64(int ordinal) => (long)GetValue(ordinal);
public override string GetString(int ordinal) => (string)GetValue(ordinal);
public override IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
public override int GetValues(object[] values)
{
throw new NotImplementedException();
}
public override bool IsDBNull(int ordinal)
{
2025-05-05 14:43:54 +08:00
if (ordinal < 0 || ordinal >= _current.ElementCount)
throw new IndexOutOfRangeException($"Invalid ordinal: {ordinal}");
var value = _current.GetElement(ordinal).Value;
return value == null || value.IsBsonNull;
2025-05-02 11:39:41 +08:00
}
public override string GetName(int ordinal)
{
2025-05-05 14:26:49 +08:00
var firstObj=_firstObj;
if (firstObj == null)
return "";
2025-05-02 14:54:14 +08:00
// 获取当前文档的字段元素列表Elements
2025-05-05 14:26:49 +08:00
var elements = firstObj.Elements.ToList();
2025-05-02 14:54:14 +08:00
// 确保 ordinal 是有效的索引
if (ordinal < 0 || ordinal >= elements.Count)
2025-05-02 14:30:13 +08:00
throw new IndexOutOfRangeException($"Invalid ordinal: {ordinal}");
2025-05-02 14:54:14 +08:00
// 返回对应索引的字段名
return elements[ordinal].Name;
2025-05-02 11:39:41 +08:00
}
public override int GetOrdinal(string name)
{
2025-05-05 14:26:49 +08:00
var firstObj = _firstObj;
2025-05-02 11:39:41 +08:00
int i = 0;
2025-05-05 14:26:49 +08:00
foreach (var elem in firstObj.Elements)
2025-05-02 11:39:41 +08:00
{
if (elem.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
return i;
i++;
}
throw new IndexOutOfRangeException($"Field '{name}' not found.");
}
public override object GetValue(int ordinal)
{
if (_current == null)
throw new InvalidOperationException("No current document.");
var element = GetElementByOrdinal(ordinal);
2025-05-05 11:50:43 +08:00
var result= BsonTypeMapper.MapToDotNetValue(element.Value);
return result;
2025-05-02 11:39:41 +08:00
}
private BsonElement GetElementByOrdinal(int ordinal)
{
if (_current == null)
throw new InvalidOperationException("No current document.");
int i = 0;
foreach (var elem in _current.Elements)
{
if (i == ordinal)
return elem;
i++;
}
throw new IndexOutOfRangeException();
}
}
2025-04-26 19:46:11 +08:00
}