我的数据库出现了令人困惑的情况。
由于我无法确定的原因,每当我从我的DbContext(称为DataRepository
)持有的DbSet中删除一个项目时,都会添加另外三个相同类型的“空”项目。
这是我的Teacher
实体的代码(它继承自User
,我使用TPT继承来处理它)。
public class Teacher
: User
{
public string Title { get; set; }
public string Email { get; set; }
public virtual Department Department { get; set; }
public virtual List<Class> Classes { get; set; }
public virtual List<Booking> Bookings { get; set; }
public Teacher()
{
Department = new Department();
InternalBookings = new List<Booking>();
Classes = new List<Class>();
Access = AccessMode.Teacher;
Title = string.Empty;
Email = string.Empty;
}
}
同样,Department
实体。
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;
}
}
编辑:以及DataRepository
代码的相关部分:
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();
}
这只会删除Db中的Booking
个实体之一,以及关联的Teacher
和Class
(因此,Db中没有孤立的实体)。
问题是在运行此代码后,DbContext中Department
的DbSet有三个额外的空项。我可以在Department
的构造函数中放置一个断点,并查看正在创建的新对象。从调用堆栈可以推断它是由迭代器创建的,但肯定不会将它添加到数据库中?
另一个奇怪的效果是,通过使用,比如Repo.Bookings.Remove(Repo.Bookings.ToList().Single(b => b.Id == 1))
,我最终得到了7个新项目。
我想我在这里缺少一些非常重要的东西,所以任何帮助都会受到赞赏。
解决方案是删除其他条目的构造函数中条目的所有初始化 - 列表初始化是正常的,而不是条目本身。
答案 0 :(得分:1)
给我几分钟的确认但是我的钱说在教师构造函数中实例化一个新部门是一个坏主意。
Teacher对象从数据库加载数据,运行构造函数并每次都创建一个新部门。
答案 1 :(得分:1)
Teacher
的空构造函数创建一个没有名称的新Department
(因此为空项)。 EF注意到“更改”并将其保存到Departments表。
EF要求无参数构造函数创建它想要从查询返回的对象,但在您的情况下,只是创建这些对象会导致更改。执行查询时内部创建的对象越多,表中获得的空白项就越多。