MongoDB - вставка нескольких типов объектов в одну коллекцию

У меня есть объекты разных классов, и я хотел бы хранить их в одной коллекции в MongoDB.

Я использую asp.net core 2.2 с MongoDB.Driver 2.8.0 и MongoDB 4.0.5. Я сделал несколько попыток.

Идея: я могу хранить все нижеперечисленные объекты в одной коллекции. В настоящее время я могу сохранить их, но я не могу их прочитать -> получение "FormatException: Element '_id' does not match any field or property of class Mongo2.Models.MongoEntity." но только после перезапуска приложения. В пустой базе данных я могу сохранить объект и получить его. Когда я закрываю приложение и не удаляю БД, получаю исключение collection.Find(book => true).ToList(); }

Я предполагаю, что я пропускаю некоторые шаги или мой подход недействителен - не смог найти никаких рабочих примеров в Интернете.

Любая помощь будет высоко ценится. Либо поделившись ссылками на рабочие решения/примеры, либо здесь.

Модель:

public class MongoEntity
{
}

[BsonIgnoreExtraElements]
public class BookLibrary : MongoEntity
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string BookLibraryId { get; set; }
    public List<Book> Library { get; set; }
}

[BsonIgnoreExtraElements]
public class Book : MongoEntity
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string BookId { get; set; }

    [BsonElement("Name")]
    public string BookName { get; set; }

    [BsonElement("Price")]
    public decimal Price { get; set; }

    [BsonElement("Category")]
    public Category Category { get; set; }

    [BsonElement("Author")]
    public Author Author { get; set; }

    [BsonElement("Date")]
    public DateTime Added { get; set; }
}

[BsonIgnoreExtraElements]
public class Author : MongoEntity
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string AuthorId { get; set; }
    [BsonElement("Author name")]
    public string Name { get; set; }
    [BsonElement("Author last name")]
    public string LastName { get; set; }
}

[BsonIgnoreExtraElements]
public class Category : MongoEntity
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string CategoryId { get; set; }
    [BsonElement("Category name")]
    public string CategoryName { get; set; }
}

Контекст данных:

public class BookContext
{
    private readonly IMongoDatabase _database;
    private readonly IMongoClient _client;

    public BookContext(IConfiguration configuration)
    {
        _client = new MongoClient(configuration.GetSection(nameof(MongoDbSettings)).Get<MongoDbSettings>().ConnectionString);
        _database = _client.GetDatabase(configuration.GetSection(nameof(MongoDbSettings)).Get<MongoDbSettings>().DatabaseName);

    }

    public List<MongoEntity> Get()
    {
        var collection = _database.GetCollection<MongoEntity>("Books");
        return collection.Find(book => true).ToList();
    }

    public void AddBsonDocument()
    {
        var author = new Author()
        {
            Name = "Name",
            LastName = "Lastname",
            AuthorId = ObjectId.GenerateNewId().ToString()
        };

        var category = new Category()
        {
            CategoryId = ObjectId.GenerateNewId().ToString(),
            CategoryName = "Non-fiction"
        };

        var book = new Book()
        {
            BookName = "Random title",
            Category = category,
            Price = 54.93m,
            Added = DateTime.Now,
            BookId = ObjectId.GenerateNewId().ToString(),
            Author = author
        };

        var lib = new BookLibrary(){BookLibraryId = ObjectId.GenerateNewId().ToString(), Library = new List<Book>()};
        lib.Library.Add(book);



        var collection = _database.GetCollection<MongoEntity>("Books");

        var list = new List<MongoEntity> {lib, book, author, category};

        collection.InsertMany(list);

    }
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
2 340
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема с полем Id. Вы сделали его настраиваемым, но MongoDB всегда будет хранить ваше свойство ID как _id внутри БД, и это нельзя изменить. Попытка изменить имя с помощью BsonElementAttribute будет просто проигнорирована.

Чтобы решить вашу проблему, вы можете попробовать следующее:

  1. Добавьте атрибут в CategoryId (и другие поля идентификаторов) с помощью BsonElement, но я не уверен, что это работает.
  2. Измените CategoryId на Id (и другие поля идентификаторов тоже)

К сожалению, ни один из них не работал. Я также заметил, что на чистой базе данных это работает. Итак, у меня есть пустая БД -> добавление записей -> я могу их получить. Когда я закрываю приложение и перезапускаю его, не удаляя базу данных, оно дает мне исключение. Я думаю, что идея с пустым классом MongoEntity неверна, но при получении коллекции мне нужно определить тип документов: var collection = _database.GetCollection<MongoEntity>("Books");

beribazoo 17.04.2019 10:22
Ответ принят как подходящий

Ответ оказался очень простым и очевидным, но как-то я его пропустил.

Тип объекта не сильно связан с именем коллекции, поэтому я мог бы использовать:

var books = _database.GetCollection<Books>("Books");
var bookLibraries = _database.GetCollection<BookLibrary>("Books");
var authors = _database.GetCollection<Author>("Books");
var categories = _database.GetCollection<Category>("Books");

Другим решением является использование типа BsonDocument:

var books = _database.GetCollection<BsonDocument>("Books");

Просто так.

Другие вопросы по теме