无法使用 DbContext 实体框架核心 SaveChanges()
Posted
技术标签:
【中文标题】无法使用 DbContext 实体框架核心 SaveChanges()【英文标题】:Cannot SaveChanges() with DbContext Entity Framework Core 【发布时间】:2020-10-15 08:37:24 【问题描述】:我对 EF 核心比较陌生,所以对我来说很简单。
我正在尝试使用 Entity Framework Core 使用数据库优先方法(因为代码优先也不起作用)创建应用程序。我已经成功地使用 EF Core 对所有模型进行了逆向工程,但是在尝试使用我的 DbContext
向数据库添加新项目时,我收到了一个视图嵌套异常消息。我的应用程序使用了两个多对多关系。
我能够将单数项添加到数据库中,问题在于将项添加到联结表中
错误发生在
ctx.Usergorups.Add(newusergroup)
在
ctx.SaveChanges();
以及所有以下Add()
声明:
Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure
.Instance '((Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure )ctx.Usergroups).Instance' 引发了“System.NotImplementedException”类型的异常 System.IServiceProvider System.NotImplementedException
发生错误的地方:
private void Create_Group(object sender, RoutedEventArgs e)
string groupname = this.namebox.Text;
if (groupname.Equals("Enter user friendly name") || (groupname.Equals("")))
MessageBox.Show("The group name cannot be the default. Enter something something descriptive");
return;
else
try
List<UserUserGroup> usergroups = new List<UserUserGroup>();
List<AccessGroupUserGroup> Accessgroupers = new List<AccessGroupUserGroup>();
Usergroups newusergroup = new Usergroups()
Name = groupname
;
var ctx = new FMS_SIRContext();
ctx.Usergroups.Add(newusergroup);
ctx.SaveChanges();
foreach (Users u in this.members.Where(u => u != null))
usergroups.Add(new UserUserGroup()
UserId = u.Id,
User = u,
UserGroupId = newusergroup.Id,
UserGroup = newusergroup
);
ctx.UserUserGroup.AddRange(usergroups);
foreach (Accessgroups a in this.acceessGroups.Where(a => a != null))
Accessgroupers.Add(new AccessGroupUserGroup()
AccessGroup = a,
AccessGroupId = a.Id,
UserGroup = newusergroup,
UserGroupId = newusergroup.Id
);
ctx.AccessGroupUserGroup.AddRange(Accessgroupers);
ctx.SaveChanges();
this.Close();
catch (Exception s)
MessageBox.Show(s.Data.ToString());
我的DbContext
班级:
public partial class FMS_SIRContext : DbContext
public FMS_SIRContext()
public FMS_SIRContext(DbContextOptions<FMS_SIRContext> options)
: base(options)
this.ChangeTracker.LazyLoadingEnabled = false;
public virtual DbSet<AccessGroupUserGroup> AccessGroupUserGroup get; set;
public virtual DbSet<Accessgroups> Accessgroups get; set;
public virtual DbSet<UserUserGroup> UserUserGroup get; set;
public virtual DbSet<Usergroups> Usergroups get; set;
public virtual DbSet<Users> Users get; set;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
if (!optionsBuilder.IsConfigured)
optionsBuilder.UseSqlServer("Data Source=az18w7413;Initial Catalog=****;Persist Security Info=True;User ID=******;Password=******;");
protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.Entity<AccessGroupUserGroup>(entity =>
entity.HasKey(e => new e.AccessGroupId, e.UserGroupId );
entity.ToTable("AccessGroupUserGroup", "asps");
entity.HasIndex(e => e.UserGroupId);
entity.Property(e => e.AccessGroupId).HasColumnName("AccessGroupID");
entity.Property(e => e.UserGroupId).HasColumnName("UserGroupID");
entity.HasOne(d => d.AccessGroup)
.WithMany(p => p.AccessGroupUserGroup)
.HasForeignKey(d => d.AccessGroupId);
entity.HasOne(d => d.UserGroup)
.WithMany(p => p.AccessGroupUserGroup)
.HasForeignKey(d => d.UserGroupId);
);
modelBuilder.Entity<Accessgroups>(entity =>
entity.ToTable("accessgroups", "asps");
entity.Property(e => e.Id).HasColumnName("ID");
entity.Property(e => e.Itname).HasColumnName("ITNAME");
entity.Property(e => e.Name).HasColumnName("NAME");
entity.Property(e => e.Permission).HasColumnName("PERMISSION");
);
modelBuilder.Entity<UserUserGroup>(entity =>
entity.HasKey(e => new e.UserId, e.UserGroupId );
entity.ToTable("UserUserGroup", "asps");
entity.HasIndex(e => e.UserGroupId);
entity.Property(e => e.UserId).HasColumnName("UserID");
entity.Property(e => e.UserGroupId).HasColumnName("UserGroupID");
entity.HasOne(d => d.UserGroup)
.WithMany(p => p.UserUserGroup)
.HasForeignKey(d => d.UserGroupId);
entity.HasOne(d => d.User)
.WithMany(p => p.UserUserGroup)
.HasForeignKey(d => d.UserId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_UserUserGroup_User");
);
modelBuilder.Entity<Usergroups>(entity =>
entity.ToTable("usergroups", "asps");
entity.Property(e => e.Id).HasColumnName("ID");
entity.Property(e => e.Name).HasColumnName("NAME");
);
modelBuilder.Entity<Users>(entity =>
entity.ToTable("Users", "asps");
entity.HasIndex(e => e.Eid)
.HasName("IX_EID")
.IsUnique();
entity.HasIndex(e => e.Id)
.HasName("IX_ID");
entity.Property(e => e.Id).HasColumnName("ID");
entity.Property(e => e.Eid)
.HasColumnName("EID")
.HasMaxLength(50);
entity.Property(e => e.FirstName).HasMaxLength(100);
entity.Property(e => e.LastName).HasMaxLength(100);
entity.Property(e => e.LocationId).HasColumnName("LocationID");
entity.Property(e => e.Mail).HasMaxLength(200);
);
OnModelCreatingPartial(modelBuilder);
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
【问题讨论】:
如果您使用的构造函数不加载选项,您的数据库上下文如何加载? 我应该删除空的构造函数吗?我的印象是基类负责配置并实例化配置。 @劳伦斯约翰逊 好吧,除非有一些我不知道的魔法,否则不会调用您的基本构造函数。您需要使用传入选项的其他构造函数。我对此不是 100% 确定的唯一原因(以及我问的原因)是因为我使用单例方法。不过,我在 MSDN 文档中没有看到像您这样的方法。所以,如果是我,是的,我会放弃那个构造函数来开始。 @LawrenceJohnson 我认为您正在做某事。在不同的线程中使用相同的 DbContext 似乎是一个依赖注入问题。如果我找到解决方案,我会发布我的解决方案。我将尝试进行适当的依赖管理。 【参考方案1】:我终于想通了(8 小时后)。这不是依赖注入问题,而是 ID 分配错误。我分配了用户、用户组、访问组和用户组的 ID,并分配了对象,因此从默认构造函数中将 id 设为 0。
private void Create_Group(object sender, RoutedEventArgs e)
string groupname = this.namebox.Text;
if (groupname.Equals("Enter user friendly name") || (groupname.Equals("")))
MessageBox.Show("The group name cannot be the default. Enter something something descriptive");
return;
else
try
List<UserUserGroup> usergroups = new List<UserUserGroup>();
List<AccessGroupUserGroup> Accessgroupers = new List<AccessGroupUserGroup>();
Usergroups newusergroup = new Usergroups()
Name = groupname
;
FMS_SIRContext ctx = new FMS_SIRContext();
ctx.Usergroups.Add(newusergroup);
ctx.SaveChanges();
foreach (Users u in members.Where(u => u != null))
usergroups.Add(new UserUserGroup()
UserId = u.Id,
//User = u,
UserGroupId = newusergroup.Id,
//UserGroup = newusergroup
);
//ctx.Usergroups.Add(newusergroup);
ctx.AddRange(usergroups);
foreach (Accessgroups a in this.acceessGroups.Where(a => a != null))
Accessgroupers.Add(new AccessGroupUserGroup()
//AccessGroup = a,
AccessGroupId = a.Id,
//UserGroup = newusergroup,
UserGroupId = newusergroup.Id
);
ctx.AddRange(Accessgroupers);
ctx.SaveChanges();
this.Close();
catch (Exception s)
MessageBox.Show(s.Data.ToString());
【讨论】:
以上是关于无法使用 DbContext 实体框架核心 SaveChanges()的主要内容,如果未能解决你的问题,请参考以下文章
如何从 DBContext(实体框架核心)中的 App.config(不是 .net 核心应用程序)读取值
应用程序中断访问 dbcontext、Asp .net 核心 web api 2.0 与实体框架核心 2.0 数据库第一种方法
由于 dotnet ef dbcontext --json 失败,无法在 Visual Studio 2019 中列出实体框架迁移