如何解决仅使用一个SaveChanges调用似乎无法更新我的数据库
我正在用自己的方法做几件事;就我而言,它们是必需的,但是优化代码并不是此问题的目的。
在这种方法中,我将创建用户,将用户添加到角色,创建目录,并在df=pd.read_json("E:/Data Science/FlipRobo/Assignments/NLP Sept project/Cell_Phones_and_Accessories.json",orient='records',dtype='dict')
df.head()
表中创建记录以将用户链接到新目录。
这里有一些数据库操作,所以我想通过只调用一次SaveChanges来尝试减少数据库的负载。
它似乎什么都没做;我没有看到添加新的首长级成员,也没有添加Directorateuser用户。但是,它将创建用户并将其添加到指定的角色。
是否可以通过这种方式在Entity Framework中对数据进行多次更改批处理,还是每次执行添加或更新记录之类的操作时都必须---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-16-bb0b9f3e9bb6> in <module>()
----> 1 df=pd.read_json("E:/Data Science/FlipRobo/Assignments/NLP Sept project/Cell_Phones_and_Accessories.json",dtype='dict')
2 df.head()
5 frames
/usr/local/lib/python3.6/dist-packages/pandas/io/json/_json.py in _parse_no_numpy(self)
1106 else:
1107 self.obj = DataFrame(
-> 1108 loads(json,precise_float=self.precise_float),dtype=None
1109 )
1110
ValueError: Expected object or value
?
DirectorateUsers
编辑
这里每个评论都有额外的型号...
await db.SaveChangesAsync()
解决方法
您需要多对多关系。尽管您有一个User表和Directorates表,所以DirectorateUsers表包含User / ApplicationUser和Directorates之间的多对多关系。因此,您必须为多对多关系定制模型。
public class ApplicationUser
{
public ApplicationUser()
{
this.Directorates = new HashSet<Directorate>();
}
....
public virtual ICollection<Directorate> Directorates { get; set; }
}
首长级模型具有
public class Directorate
{
public Directorate()
{
this.Users = new HashSet<ApplicationUser>();
}
public virtual ICollection<ApplicationUser> Users{ get; set; }
}
现在DbContext类看起来像...
public class AppDBContext : DBContext
{
public AppDBContext() : base("DefaultConnectionString")
{
}
public DbSet<ApplicationUser> Users{ get; set; }
//or public DbSet<User> Users{ get; set; } //if ApplicationUser doesn't work
public DbSet<Directorate> Directorates{ get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//Configure a Many-to-Many Relationship using Fluent API
modelBuilder.Entity<User>() //or ApplicationUser
.HasMany<Directorate>(s => s.Directorates)
.WithMany(c => c.Users)
.Map(cs =>
{
cs.MapLeftKey("UserId");
cs.MapRightKey("DirectorateId");
cs.ToTable("DirectorateUser");
});
}
}
此映射创建了良好的关系。请检查以下链接以了解多对多关系。 https://www.entityframeworktutorial.net/code-first/configure-many-to-many-relationship-in-code-first.aspx
现在检查您的代码db.SaveChangesAsync();或不等待,只需db.SaveChanges()。 希望它能起作用。记住您必须以正确的方式映射对象。
,我看到,当您创建Directorateate和DirectorateUser时,您正在使用“ user”变量,该变量可能未引用数据库中的那个。
使用以下变量代替“ user”来创建董事会,DirectorateUser可以解决该问题。
var userDb = await _userManager.FindByNameAsync(user.UserName)
,
对我来说,问题在于此。
db.Entry(municipality).State = EntityState.Modified;
await db.SaveChangesAsync();
这只会启动与市政相关的保存更改。
但是,我认为您应该有这样的东西。
//set all objects that need to be updated in a modified state
db.Entry(municipality).State = EntityState.Modified;
db.Entry(directorate).State = EntityState.Modified;
db.Entry(directorateUser).State = EntityState.Modified;
//finally save all the changes to the database.
await db.SaveChangesAsync();
这就是我要的方法。
,我看到您正在使用UserManager
访问IdentityDbContext
。身份框架使用IUserStore
的实例将两者粘合在一起。但是,您已经注意到,每个操作都会立即保存更改。
默认实现UserStore
已经具有布尔属性AutoSaveChanges
,以防止每次操作都进行保存,但是似乎没有明显的方法可以访问此属性。
您可以用自己的实现替换IUserStore
服务(根据UserManager's AutoSaveChanges in .NET Core 2.1);
public class CustomUserStore : UserStore<IdentityUser>
{
public CustomUserStore(ApplicationDbContext context)
: base(context)
{
AutoSaveChanges = false;
}
}
services.AddScoped<IUserStore<IdentityUser>,CustomUserStore>();
尽管您随后需要确保所有UserManager / SigninManager调用后面都带有另一个显式保存。
或者您可以添加IUserStore
作为依赖项,假设它是UserStore
的实例,并在方法周围更改AutoSaveChanges值;
private UserStore<IdentityUser,IdentityRole,DbContext> store;
public Controller(IUserStore<IdentityUser> store)
{
this.store = store as UserStore<IdentityUser,DbContext>;
}
public async Task<ActionResult> Create(...){
try{
store.AutoSaveChanges = false;
...
}finally{
store.AutoSaveChanges = true;
}
}
请注意,您需要哪种UserStore通用类型,取决于您使用的IdentityContext通用类型。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。