Конструктор MongoDB.Bson.ObjectId() не работает в .NET Core 2

У меня есть первый проект, который пытается получить значение из mongodb, используя MongoDB.Driver. Я могу подключиться к базе данных и «GetAll», но когда делаю запрос, которому нужен ObjectId, я получаю это исключение:

Exception has occurred: CLR/System.IndexOutOfRangeException
An exception of type 'System.IndexOutOfRangeException' occurred in MongoDB.Bson.dll but was not handled in user code: 'Index was outside the bounds of the array.'

если быть более конкретным:

at MongoDB.Bson.ObjectId.FromByteArray(Byte[] bytes, Int32 offset, Int32& a, Int32& b, Int32& c)
   at MongoDB.Bson.ObjectId..ctor(String value)
   at TodoApi.Controllers.TodoController.GetById(String id) ...

Метод GetById:

[HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(string id)
{
    var objId = new ObjectId(id); << this line exceptions occures
    var item = objds.GetTodoItem(objId);

    if (item == null) { return NotFound(); }

    return new ObjectResult(item);
}

Метод GetTodoItem от DataAcess:

public TodoItem GetTodoItem(ObjectId id)
{
    var res = Query<TodoItem>.EQ(p=>p.Id,id);
    return _db.GetCollection<TodoItem>("TodoApi").FindOne(res);
}

.csproj

  <ItemGroup>
    <PackageReference Include="MongoDB.Driver" Version="2.5.0" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="MongoDB.Driver.Core" Version="2.5.0" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="MongoDB.Bson" Version="2.5.0" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="mongocsharpdriver" Version="2.5.0" />
  </ItemGroup>

person Fernando Veras    schedule 16.04.2018    source источник


Ответы (2)


Вы можете сгенерировать новый ObjectId следующим образом:

ObjectId.GenerateNewId();

Но, скорее всего, вы не найдете в своей базе ни одного документа с таким идентификатором. Обычно вы генерируете ObjectId, когда хотите выполнить вставку и не хотите, чтобы Mongo назначал случайный идентификатор вашему вновь вставленному документу (скажем, вы хотите вернуть этот идентификатор обратно пользователю).

Теперь, если вы ищете конкретный документ с id = 5a71ae10a41e1656a4a50902, вы можете сделать следующее:

var id = "5a71ae10a41e1656a4a50902";
var context = new YourContext();
var builder = Builders<TodoItem>.Filter;
var filter = builder.Eq(x => x.Id, ObjectId.Parse(id));
var result = await context.TodoItemCollection.FindAsync(filter);
person Mahdi    schedule 16.04.2018
comment
Теперь я понимаю. Я изменил свой метод поиска ID не по ObjectID public TodoItem GetTodoItem(int id) { var res = Query<TodoItem>.EQ(t => t.TodoId, id); return _db.GetCollection<TodoItem>("TodoApi").FindOne(res); } - person Fernando Veras; 16.04.2018

Проблема в строке о создании нового objectID. mongoDB автоматически предоставляет идентификаторы документов по умолчанию, и вы сначала находите идентификатор, а затем запрашиваете коллекцию, используя его.

Конечно, вы можете изменить поведение по умолчанию — см.

http://codingcanvas.com/using-mongodb-_id-field-with-c-pocos/

Измените эту строку:

var objId = new ObjectId(id); 

Что-то вроде этого (вы должны изменить аргумент objectid.Parse() на свои значения.

var query_id = Query.EQ("_id",    
ObjectId.Parse("50ed4e7d5baffd13a44d0153"));
var entity = dbCollection.FindOne(query_id);
return entity.ToString();

Кроме того, в этой строке есть опечатка, вы имели в виду objId после знака =?

 var item = objds.GetTodoItem(objId)

Кредиты: запросить MongoDB с использованием 'ObjectId'

person salah-1    schedule 16.04.2018