DbContext 不更新数据库
DbContext not updating database
当我保存对 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();
。
此外,您使用的是静态 classes,如果您使用的是依赖注入,则情况不应如此。 DI 将处理您的对象的生命周期。
您的 class 没有按应有的方式定义,您有一些格式错误,应该看起来像这样:
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 以及如何 avoid those foreach cycles using select, check the default net core coding standards。
编辑
I'm curious, would LINQ provide any performance benefits in this case
vs just a regular for loop?
更多的是关于代码的可读性和可维护性,在答案中我已经把 link 放到 post 中更好地解释了,你正在创建 technical debt你的代码,你正在初始化数组并填充它们,处理索引等等......,但它减少到这个:
什么更容易阅读?这个:
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
和其他 control structures 更加熟悉为止。这是结构化编程,本身就是一个话题
Also how would I pass the roadmapService object to the Controller
constructor, I've just never seen that.
这就是依赖注入的神奇之处,让系统为你创建对象,你只需要询问类型即可。
这也是一个很大的话题,你应该看看我之前的link到微软的文档,但是基本上,你所要做的就是定义classes作为依赖,所以,当你要求一个,系统本身检查依赖关系,以及该对象的依赖关系,直到解决所有依赖关系树。
有了这个,如果你需要在你的 class 后面增加一个依赖,你可以直接添加但你不需要修改所有使用那个 class 的 classes .
要在控制器中使用它,请 check the official docs,您只需将依赖项添加到构造函数中,然后赢!,基本上分为两部分:
加入你的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();
}
当我保存对 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();
。
此外,您使用的是静态 classes,如果您使用的是依赖注入,则情况不应如此。 DI 将处理您的对象的生命周期。
您的 class 没有按应有的方式定义,您有一些格式错误,应该看起来像这样:
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 以及如何 avoid those foreach cycles using select, check the default net core coding standards。
编辑
I'm curious, would LINQ provide any performance benefits in this case vs just a regular for loop?
更多的是关于代码的可读性和可维护性,在答案中我已经把 link 放到 post 中更好地解释了,你正在创建 technical debt你的代码,你正在初始化数组并填充它们,处理索引等等......,但它减少到这个:
什么更容易阅读?这个:
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
和其他 control structures 更加熟悉为止。这是结构化编程,本身就是一个话题
Also how would I pass the roadmapService object to the Controller constructor, I've just never seen that.
这就是依赖注入的神奇之处,让系统为你创建对象,你只需要询问类型即可。
这也是一个很大的话题,你应该看看我之前的link到微软的文档,但是基本上,你所要做的就是定义classes作为依赖,所以,当你要求一个,系统本身检查依赖关系,以及该对象的依赖关系,直到解决所有依赖关系树。
有了这个,如果你需要在你的 class 后面增加一个依赖,你可以直接添加但你不需要修改所有使用那个 class 的 classes .
要在控制器中使用它,请 check the official docs,您只需将依赖项添加到构造函数中,然后赢!,基本上分为两部分:
加入你的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();
}