C# EF 6:删除实体会导致空对象
我的数据库中出现了令人困惑的情况。 出于无法确定的原因,每当我从DbContext(称为C# EF 6:删除实体会导致空对象,c#,database,entity-framework,C#,Database,Entity Framework,我的数据库中出现了令人困惑的情况。 出于无法确定的原因,每当我从DbContext(称为DataRepository)持有的DbSet中删除一个项时,就会再添加三个相同类型的“空”项 下面是我的教师实体的代码(它确实继承自用户,我使用TPT继承来处理它) 编辑:以及数据存储库的相关部分代码: public class DataRepository : DbContext { public virtual DbSet<Booking> Bookings { get; s
DataRepository
)持有的DbSet中删除一个项时,就会再添加三个相同类型的“空”项
下面是我的教师
实体的代码(它确实继承自用户
,我使用TPT继承来处理它)
编辑:以及数据存储库的相关部分
代码:
public class DataRepository
: DbContext
{
public virtual DbSet<Booking> Bookings { get; set; }
public virtual DbSet<Department> Departments { get; set; }
public virtual DbSet<Class> Classes { get; set; }
public DataRepository()
: base(@"data source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=" + Path + ";Database=Data;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework")
{
Database.SetInitializer(new DropCreateDatabaseAlways<DataRepository>());
}
}
这只需删除数据库中的一个预订
实体,以及相关的教师
和类
(因此,数据库中没有孤立实体)
问题是,运行此代码后,DbContext中的部门
s的DbSet有三个额外的空项。我可以在Department
的构造函数中设置断点,并查看正在创建的新对象。从调用堆栈可以推断它是由迭代器创建的,但肯定不会将它添加到数据库中
另一个奇怪的效果是,通过使用,比如说Repo.Bookings.Remove(Repo.Bookings.ToList().Single(b=>b.Id==1))
,我得到了7个新项目
我想我错过了一件非常重要的事情,所以非常感谢您的帮助
解决方案是删除其他条目的构造函数中条目的所有初始化-列表初始化是可以的,只是条目本身不可以。给我几分钟时间确认,但我的钱说在教师构造函数中实例化一个新部门是个坏主意
教师对象从数据库加载数据,每次运行构造函数并创建一个新部门。教师的空构造函数创建一个没有名称的新部门(因此为空项)。EF注意到“更改”并将其保存到Departments表中
EF需要无参数构造函数来创建它希望从查询返回的对象,但在您的情况下,简单地创建这些对象会导致更改。执行查询时,它在内部创建的对象越多,表中的空项就越多。尝试将“删除”替换为“Where”@User2012384我试图从数据库中删除项,而不是筛选项。@Moho更新-我最初只是省略了它,因为它没有什么特别之处。谢谢,我从来没有想到,如果没有显式添加新对象,EF可能能够检测到它们。它通常非常擅长跟踪更改,除非你告诉它不要这样做。当两个对象之间没有明确的或常规的关系时,它主要会失效,因此您必须手动清理。
public class Department
{
public string Name { get; set; }
public virtual List<Teacher> Teachers { get; set; }
public virtual List<Room> Rooms { get; set; }
public Department()
{
Teachers = new List<Teacher>();
Rooms = new List<Room>();
Name = string.Empty;
}
}
public class DataRepository
: DbContext
{
public virtual DbSet<Booking> Bookings { get; set; }
public virtual DbSet<Department> Departments { get; set; }
public virtual DbSet<Class> Classes { get; set; }
public DataRepository()
: base(@"data source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=" + Path + ";Database=Data;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework")
{
Database.SetInitializer(new DropCreateDatabaseAlways<DataRepository>());
}
}
using (DataRepository Repo = new DataRepository())
{
Repo.Bookings.Remove(Repo.Bookings.Single(b => b.Id == 1));
Repo.Teachers.Remove(Repo.Teachers.Single(t => t.FirstName == "R...."));
Repo.Classes.Remove(Repo.Classes.Single(c => c.Owner == Repo.Teachers.FirstOrDefault(t => t.FirstName == "R....")));
Repo.SaveChanges();
}