У меня есть объекты разных классов, и я хотел бы хранить их в одной коллекции в 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);
}
}





Проблема с полем Id. Вы сделали его настраиваемым, но MongoDB всегда будет хранить ваше свойство ID как _id внутри БД, и это нельзя изменить. Попытка изменить имя с помощью BsonElementAttribute будет просто проигнорирована.
Чтобы решить вашу проблему, вы можете попробовать следующее:
CategoryId (и другие поля идентификаторов) с помощью BsonElement, но я не уверен, что это работает.CategoryId на Id (и другие поля идентификаторов тоже)Ответ оказался очень простым и очевидным, но как-то я его пропустил.
Тип объекта не сильно связан с именем коллекции, поэтому я мог бы использовать:
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");
Просто так.
К сожалению, ни один из них не работал. Я также заметил, что на чистой базе данных это работает. Итак, у меня есть пустая БД -> добавление записей -> я могу их получить. Когда я закрываю приложение и перезапускаю его, не удаляя базу данных, оно дает мне исключение. Я думаю, что идея с пустым классом MongoEntity неверна, но при получении коллекции мне нужно определить тип документов:
var collection = _database.GetCollection<MongoEntity>("Books");