DbContext не обновляет базу данных - PullRequest
0 голосов
/ 29 мая 2019

Когда я сохраняю изменения в DbContext, он не обновляет мою базу данных. Ошибок тоже нет.

Да, данные входящей формы заполнены. Да, строка подключения верна, я знаю это, потому что могу получать данные из базы данных совершенно нормально. Если это уместно, это отношения многие ко многим.

Насколько вам интересна дорожная карта, она может быть связана со многими тегами.

    public static class RoadmapService
    {
        static ConkerDbEntities dbContext;
        public static void createDbContext(ConkerDbEntities _dbContext)
        {
            dbContext = _dbContext;
        }

        public static void addToDatabase(Form form)
        {
            Roadmaps roadmap = new Roadmaps { RoadmapTitle = form.title, 
                                              RoadmapSummary = form.summary, 
                                              RoadmapBody = form.body };

            var tags = new Tags[form.tags.Length];

            for(int i = 0; i < tags.Length; i++)
            {
                tags[i] = new Tags();
                tags[i].TagId = form.tags[i];
            }

            var roadmapTags = new RoadmapTags[form.tags.Length];

            for(int i = 0; i < tags.Length; i++)
            {
                roadmapTags[i] = new RoadmapTags{Roadmap = roadmap, Tag = tags[i]};
            }

            dbContext.AddRange(roadmapTags);
            dbContext.SaveChangesAsync();
        }
    }
}

Там, где создается dbcontext, это конструктор Startup.cs

        public static SearchEngine engine;
        public static ConkerDbEntities dbContext;

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;

            dbContext = new ConkerDbEntities();

            RoadmapService.createDbContext(dbContext);
            engine = new SearchEngine(dbContext);

        }

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

1 Ответ

2 голосов
/ 29 мая 2019

Вы используете асинхронное программирование, но ваш метод не асинхронный.

используйте dbContext.SaveChangesAsync();, когда у вас есть асинхронные методы, используйте dbContext.SaveChanges();, когда не асинхронный.

Также выиспользуют статические классы, это не должно иметь место, если вы используете внедрение зависимостей.DI будет обрабатывать жизненный цикл ваших объектов.

Ваш класс не определен должным образом, у вас есть некоторые ошибки формата, и он должен выглядеть примерно так:

public class RoadmapService
{
    private readonly ConkerDbEntities _dbContext;

    public RoadmapService(ConkerDbEntities dbContext)
    {
        _dbContext = dbContext;
    }

    public async Task AddToDatabase(Form form)
    {
        Roadmaps roadmap = new Roadmaps {
            RoadmapTitle = form.title, 
            RoadmapSummary = form.summary, 
            RoadmapBody = form.body 
        };

        var tags = new Tags[form.tags.Length];

        for(int i = 0; i < tags.Length; i++)
        {
            tags[i] = new Tags();
            tags[i].TagId = form.tags[i];
        }

        var roadmapTags = new RoadmapTags[form.tags.Length];

        for(int i = 0; i < tags.Length; i++)
        {
            roadmapTags[i] = new RoadmapTags{Roadmap = roadmap, Tag = tags[i]};
        }

        _dbContext.AddRange(roadmapTags);
        _dbContext.SaveChangesAsync();
    }
}

Тогда в вашемконтроллер вы можете использовать свой сервис как есть

public class OrdersController : Controller
{
    private readonly RoadmapService _roadmapService;

    public OrdersController(RoadmapService roadmapService)
    {
        _roadmapService = roadmapService;
    }

    [HttpGet]
    [Route("api/[controller]/{folio}")]
    public async Task<IActionResult> Status(string folio)
    {
        await _roadmapService.AddToDatabase(something);
        return Ok();
    }
}

Я также рекомендовал бы изучить linq и как вы можете избежать этих циклов foreach с помощью select, проверить по умолчанию net coreстандарты кодирования .

Edit

Мне интересно, обеспечит ли LINQ какие-либо преимущества в производительности в этом случае по сравнению с обычным циклом for?

Это больше о удобочитаемости и удобстве сопровождения вашего кода, в ответе я уже поместил ссылку на пост, где лучше объясняется, вы создаете технический долг в своем коде, вы инициализируете массивы изаполняя их, обрабатывая индексы и многое другое ..., но сводится к этому:

Что легче читать?это:

public async Task AddToDatabase(Form form)
{
    Roadmaps roadmap = new Roadmaps {
        RoadmapTitle = form.title, 
        RoadmapSummary = form.summary, 
        RoadmapBody = form.body 
    };

    var tags = new Tags[form.tags.Length];

    for(int i = 0; i < tags.Length; i++)
    {
        tags[i] = new Tags();
        tags[i].TagId = form.tags[i];
    }

    var roadmapTags = new RoadmapTags[form.tags.Length];

    for(int i = 0; i < tags.Length; i++)
    {
        roadmapTags[i] = new RoadmapTags{Roadmap = roadmap, Tag = tags[i]};
    }

    _dbContext.AddRange(roadmapTags);
    _dbContext.SaveChangesAsync();
}

или это

    public async Task AddToDatabase(Form form)
    {
        var roadmap = new Roadmap {
            RoadmapTitle = form.title, 
            RoadmapSummary = form.summary, 
            RoadmapBody = form.body 
        };

        var roadmapTags = form.Tags
            .Select(tagId => new Tag        // First we take our form.tags and convert it to Tag objects
            {
                TagId = tagId
            })
            .Select(tag => new RoadmapTags  // Then we take the result of the previous conversion and we 
            {                               // transform again to RoadmapTags, we even could do this in one pass
                Roadmap = roadmap,          // but this way is more clear what the transformations are
                Tag = tag
            })
            .ToList();

        _dbContext.AddRange(roadmapTags);
        await _dbContext.SaveChangesAsync();
    }

Если вы только начали изучать программирование, вы можете игнорировать это, пока не почувствуете себя более комфортно с for, foreach, while и другие управляющие структуры .Это структурное программирование, и это отдельная тема.

Также, как бы я передал объект roadmapService в конструктор Controller, я просто никогда не видел этого.

В этом волшебство внедрения зависимостей, просто позвольте системе создать объект для вас, вам просто нужно запросить тип.

Это также большая тема, вы должны проверить мою предыдущую ссылку наДокументация Microsoft, но в основном все, что вам нужно сделать, это определить классы как зависимости, поэтому, когда вы запрашиваете один, система сама проверяет зависимости и зависимости этих объектов до тех пор, пока не разрешит все дерево зависимостей.

При этом, если вам нужна еще одна последняя зависимость в вашем классе, вы можете добавить напрямую, но вам не нужно изменять все классы, которые используют этот класс.

Чтобы использовать это в контроллере, проверьте официальные документы , вам просто нужно добавить свои зависимости в конструктор и выиграть !, в основном две части:

Добавьте в свой Startup.class

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddTransient<MySpecialClassWithDependencies>();
    ...
}

Затем в вашем контроллере:

public class HomeController : Controller
{
    private readonly MySpecialClassWithDependencies _mySpecialClassWithDependencies;

    public HomeController(MySpecialClassWithDependencies mySpecialClassWithDependencies)
    {
        _mySpecialClassWithDependencies = mySpecialClassWithDependencies;
    }

    public IActionResult Index()
    {
        // Now i can use my object here, the framework already initialized for me!
        return View();
    }
...