【发布时间】:2020-09-30 09:19:11
【问题描述】:
我在我的方法中做了几件事;就我而言,它们是必要的,但优化代码不是这个问题的目的。
在这种方法中,我创建了一个用户,将用户添加到一个角色,创建一个 Directorate 并在 DirectorateUsers 表中创建一条记录以将用户链接到新的 Directorate。
这里有一些数据库操作,所以我想尝试通过只调用一次 SaveChanges 来减少数据库的负载。
它似乎没有做任何事情;我没有看到添加新的董事,也没有添加董事用户。但是,它会创建用户并将其添加到指定的角色。
是否可以通过这种方式在 Entity Framework 中批量更改数据,还是每次我执行添加或更新记录等操作时都必须await db.SaveChangesAsync()?
[HttpPost]
public async Task<ActionResult> Create([Bind(Include = "MunicipalityId,DirectorateName,UserEmailAddress, UserPassword")] RegisterDirectorateViewModel model)
{
try
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.UserEmailAddress, Email = model.UserEmailAddress };
var createUserResult = await UserManager.CreateAsync(user, model.UserPassword);
if (createUserResult.Succeeded)
{
// Add the user to the directorate role.
await UserManager.AddToRoleAsync(user.Id, nameof(SystemRoles.Directorate));
// Generate the directorate and add the user to it.
var municipality = await db.Municipalities.FindAsync(model.MunicipalityId);
var directorate = new Directorate
{
Action = MetaAction.Create,
ActionBy = user,
ActionDate = DateTime.Now,
Municipality = municipality,
Name = model.DirectorateName
};
db.Directorates.Add(directorate);
var directorateUser = new DirectorateUser
{
Directorate = directorate,
User = user
};
db.DirectorateUsers.Add(directorateUser);
// Expire the token so that it can't be used again.
municipality.TokenExpiryDate = DateTime.Now;
db.Entry(municipality).State = EntityState.Modified;
await db.SaveChangesAsync();
// Sign in the user and redirect to the dashboard.
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
return RedirectToAction("Index", "Dashboard");
}
}
return View(model);
}
catch (Exception ex)
{
TempData["err"] = ex;
return RedirectToAction("Create");
}
}
编辑
这是每个 cmets 的额外模型...
public class Directorate
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Municipality Municipality { get; set; }
public ApplicationUser ActionBy { get; set; }
public DateTime ActionDate { get; set; }
public MetaAction Action { get; set; }
}
public class DirectorateUser
{
public int Id { get; set; }
public virtual Directorate Directorate { get; set; }
public virtual ApplicationUser User { get; set; }
}
public class SubdirectorateUser
{
public int Id { get; set; }
public virtual Subdirectorate Subdirectorate { get; set; }
public virtual ApplicationUser User { get; set; }
}
【问题讨论】:
-
使用单个 SaveChanges 或 SaveChangesAsync 可以工作,并保存所有批量更改。毫无疑问。你的代码可能会抛出吗? catch 块中没有日志记录,因此任何可能的异常都可能丢失。
-
发布一个 minimal 示例来演示该问题 - 只是一个控制台应用程序、创建新 DbContext 的必要类和代码、添加一些实体然后调用
SaveChanges。 -
@PanagiotisKanavos 完全没有错误;执行通过仪表板重定向并且永远不会进入 catch 块。不贴9000行代码,怎么发这样的例子来演示?
-
如果
Directorate和DirectoryUser实体只有此处显示的字段,我描述的是大约 10 行和另外 15 行 -
添加了模型...虽然保留专有信息有一些话要说...好吧...专有的。
标签: c# asp.net-mvc entity-framework