Задать вопрос
@GineTik

При каждой новой миграции Bogus генерирует (обновляет) новые данные, как это убрать?

Для генерации тестовых данных я использую класс Faker библиотеки Bogus. Я сгенерировал данные и создал миграцию, позже, я решил добавить данные и для таблицы заказов. И вот, когда я добавил миграцию, то кроме добавления заказов, также начались обновляться все данные из других таблиц. Как это исправить? Может, можно указать не обновлять данные для каких-то таблиц или если другие варианты?

Вот код:
public static class FakeDatasExtension
    {
        private const int CATEGORIES_COUNT = 6;
        private const int FURNITURE_COUNT = 50;
        private const int REVIEW_COUNT = 60;
        private const int ORDER_COUNT = 30;

        private const string LOCALE = "en";

        private static ModelBuilder _builder; // created this field because there is only one public method

        public static void LoadFakeDatas(this ModelBuilder builder)
        {
            ArgumentNullException.ThrowIfNull(builder);

            _builder = builder;

            var categories = LoadFakeCategories();
            var furnitures = LoadFakeFurniture(categories);
            var users = LoadFakeUsers();
            LoadFakeRewiews(users, furnitures);
            LoadFakeOrders(users, furnitures);
        }

        private static IEnumerable<Category> LoadFakeCategories()
        {
            var faker = new Faker<Category>(LOCALE)
                .RuleFor(x => x.Id, f => f.IndexFaker + 1)
                .RuleFor(x => x.Name, f => f.Commerce.Department());

            return LoadDatasToDb(faker.Generate(CATEGORIES_COUNT));
        }

        private static IEnumerable<Furniture> LoadFakeFurniture(IEnumerable<Category> categories)
        {
            var faker = new Faker<Furniture>(LOCALE)
                .RuleFor(x => x.Id, f => f.IndexFaker + 1)
                .RuleFor(x => x.Name, f => f.Commerce.ProductName())
                .RuleFor(x => x.Description, f => f.Lorem.Paragraph())
                .RuleFor(x => x.Price, f => f.Random.Decimal(10, 1000))
                .RuleFor(x => x.CategoryId, f => f.PickRandom(categories).Id);

            return LoadDatasToDb(faker.Generate(FURNITURE_COUNT));
        }

        private static IEnumerable<User> LoadFakeUsers()
        {
            var user = new User()
            {
                Id = 1,
                UserName = "user@gmail.com",
                Email = "user@gmail.com",
                NormalizedEmail = "USER@GMAIL.COM",
                NormalizedUserName = "USER@GMAIL.COM",
            };
            var moderator = new User()
            {
                Id = 2,
                UserName = "moderator@gmail.com",
                Email = "moderator@gmail.com",
                NormalizedEmail = "MODERATOR@GMAIL.COM",
                NormalizedUserName = "MODERATOR@GMAIL.COM",
            };
            var admin = new User()
            {
                Id = 3,
                UserName = "admin@gmail.com",
                Email = "admin@gmail.com",
                NormalizedEmail = "ADMIN@GMAIL.COM",
                NormalizedUserName = "ADMIN@GMAIL.COM",
            };

            const string PASSWORD = "password";

            user.PasswordHash = new PasswordHasher<User>().HashPassword(user, PASSWORD);
            moderator.PasswordHash = new PasswordHasher<User>().HashPassword(moderator, PASSWORD);
            admin.PasswordHash = new PasswordHasher<User>().HashPassword(admin, PASSWORD);

            LoadDatasToDb(new[]
            {
                new IdentityUserRole<int>() { UserId = 1, RoleId = 1 },
                new IdentityUserRole<int>() { UserId = 2, RoleId = 2 },
                new IdentityUserRole<int>() { UserId = 3, RoleId = 3 },
            });

            return LoadDatasToDb(new[]
            {
                user,
                moderator,
                admin,
            });
        }

        private static void LoadFakeRewiews(IEnumerable<User> users, IEnumerable<Furniture> furnitures)
        {
            var faker = new Faker<Review>(LOCALE)
                .RuleFor(x => x.Id, f => f.IndexFaker + 1)
                .RuleFor(x => x.Comment, f => f.Lorem.Paragraph())
                .RuleFor(x => x.Evaluation, f => f.Random.Int(1, 11))
                .RuleFor(x => x.DateTime, f => DateTime.UtcNow)
                .RuleFor(x => x.UserId, f => f.PickRandom(users).Id)
                .RuleFor(x => x.FurnitureId, f => f.PickRandom(furnitures).Id);

            LoadDatasToDb(faker.Generate(REVIEW_COUNT));
        }

        private static void LoadFakeOrders(IEnumerable<User> users, IEnumerable<Furniture> furnitures)
        {
            var faker = new Faker<Order>(LOCALE)
                .RuleFor(x => x.Id, f => f.IndexFaker + 1)
                .RuleFor(x => x.Count, f => f.Random.Int(1, 5))
                .RuleFor(x => x.DateOfOrder, f => f.Date.Between(DateTime.UtcNow.AddMonths(-1), DateTime.UtcNow)) // AddMonths(-1) - substract one month
                .RuleFor(x => x.UserId, f => f.PickRandom(users).Id)
                .RuleFor(x => x.FurnitureId, f => f.PickRandom(furnitures).Id);

            LoadDatasToDb(faker.Generate(ORDER_COUNT));
        }

        private static IEnumerable<TEntity> LoadDatasToDb<TEntity>(IEnumerable<TEntity> entities)
            where TEntity : class
        {
            _builder.Entity<TEntity>().HasData(entities);
            return entities;
        }
    }


Метод я вызываю в OnModelCreating в DbContext.

Буду рад любому ответу или намеку!) Спасибо.
  • Вопрос задан
  • 110 просмотров
Подписаться 1 Простой 4 комментария
Решения вопроса 1
Проблема в том что HasData должен по хорошему быть неизменным.
Тебе следует вместо HasData создать новую миграцию и уже в ней генерить данные.
+ в Bogus можно передать сид, чтобы данные генерировались стабильные.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы