Когда я сохраняю изменения в 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);
}
Я не получаю ошибок, и в базу данных ничего не добавляется. Я, вероятно, делаю что-то в корне неправильно здесь. Заранее спасибо.
Вы используете асинхронное программирование, но ваш метод не является асинхронным.
используйте 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, проверьте стандарты кодирования ядра сети по умолчанию.
I'm curious, would LINQ provide any performance benefits in this case vs just a regular for loop?
Это больше о читаемости и ремонтопригодности вашего кода, в ответ я уже дал ссылку на пост, где лучше объясняется, вы создаете технический долг в своем коде, вы инициализируете массивы и заполняете их, обрабатываете индексы и многое другое.. ., но сводится к этому:
Что легче читать? это:
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
и другими структуры управления. Это структурное программирование, и это отдельная тема.
Also how would I pass the roadmapService object to the Controller constructor, I've just never seen that.
Это магия внедрения зависимостей, просто позвольте системе создать объект для вас, вам просто нужно запросить тип.
Это также большая тема, вы должны проверить мою предыдущую ссылку на документацию 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();
}
Кроме того, как бы я передал объект roadmapService конструктору контроллера, я просто никогда этого не видел.
@Wasiim-Ouro Добавлено несколько пояснений
вау, код теперь такой шелковистый. Я вижу, что вы имеете в виду сейчас. Большое человеческое спасибо!!!!!!!!!
Мне любопытно, предоставит ли LINQ какие-либо преимущества в производительности в этом случае по сравнению с обычным циклом for? и спасибо за подробный и отличный ответ и готовность не обращать внимания на мой мусорный код.