当添加测试数据(保留)时,实体框架在实际行之前添加一个空的空行
我有一个问题,即在向数据库添加保留或我的测试数据时(使用实体框架),它创建了一个空其中一个表中的空行。当添加测试数据(保留)时,实体框架在实际行之前添加一个空的空行
我有3个表
- 预订
- ContactPerson
- 客房
有一个许多人Reservation
和Rooms
之间一对多的关系。 ContactPerson
和Reservation
之间有一对多关系。
我正在使用代码优先的方法。
预订类:
public class Reservation
{
public Reservation()
{
Room = new List<Room>();
ContactPerson = new ContactPerson();
}
public int ReservationID { get; set; }
public string ReservationNumber { get; set; }
public DateTime CheckInDate { get; set; }
public DateTime CheckOutDate { get; set; }
public int ContactPersonID { get; set; }
public virtual ContactPerson ContactPerson { get; set; }
public virtual ICollection<Room> Room { get; set; }
}
房类:
public class Room
{
public int ID { get; set; }
public string RoomNumber { get; set; }
public bool Occupied { get; set; }
public bool Smoking { get; set; }
public bool Minibar { get; set; }
public int Beds { get; set; }
public RoomTypeEnum? RoomType { get; set; }
public virtual ICollection<Reservation> Reservations { get; set; }
}
public enum RoomTypeEnum
{
Single = 0, Double = 1, Family = 2, Suite = 3
}
ContactPerson类:
public class ContactPerson
{
public int ContactPersonID { get; set; }
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public Nationality NationalityType { get; set; }
public virtual ICollection<Reservation> Reservations { get; set; }
}
public enum Nationality
{
Denmark, Germany, England, France, Holland, Belgium, Norway, Sweden, Finland
}
我DataContext
类:
public interface IDataContext
{
DbSet<Room> Rooms { get; }
DbSet<Reservation> Reservations { get; }
DbSet<ContactPerson> ContactPersons { get; }
int SaveChanges();
void MarkAsModified(Reservation item);
void MarkRoomAsModified(Room item);
void CreateReservation(Reservation item);
}
public class DataContext : DbContext, IDataContext
{
public DataContext() : base("DataContext")
{
}
// DbSet to bookings
public DbSet<Reservation> Reservations { get; set; }
public DbSet<ContactPerson> ContactPersons { get; set; }
public DbSet<Room> Rooms { get; set; }
public void MarkAsModified(Reservation item)
{
Entry(item).State = EntityState.Modified;
}
public void MarkRoomAsModified(Room item)
{
Entry(item).State = EntityState.Modified;
}
public void CreateReservation(Reservation item)
{
Reservations.Add(item);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Reservation>()
.HasMany(c => c.Room).WithMany(i => i.Reservations)
.Map(t => t.MapLeftKey("ReservationID")
.MapRightKey("RoomID")
.ToTable("RoomReservation"));
}
}
我将测试数据时使用的迁移正在生成的Configuration
类。
配置:
protected override void Seed(WebApplication1.DAL.DataContext context)
{
var reservations = new List<Reservation>
{
new Reservation{ReservationNumber = "123456789", CheckInDate = DateTime.Parse("2016-01-01"), CheckOutDate = DateTime.Parse("2016.01.15"), ContactPersonID = 1
}
};
reservations.ForEach(b => context.Reservations.AddOrUpdate(r => r.ReservationID, b));
context.SaveChanges();
var contactPersons = new List<ContactPerson>
{
new ContactPerson{Title = "Mr" ,FirstName = "Anders",LastName = "Christensen", Email = "[email protected]", NationalityType = Nationality.Denmark, PhoneNumber = "44216731" }
};
contactPersons.ForEach(b => context.ContactPersons.AddOrUpdate(c => c.ContactPersonID, b));
context.SaveChanges();
var rooms = new List<Room>
{
new Room {RoomNumber = "101", Beds = 1, RoomType = RoomTypeEnum.Single, Minibar = true, Occupied = true, Smoking = false},
new Room {RoomNumber = "102", Beds = 1, RoomType = RoomTypeEnum.Single, Minibar = true, Occupied = true, Smoking = false},
new Room {RoomNumber = "103", Beds = 1, RoomType = RoomTypeEnum.Single, Minibar = true, Occupied = false, Smoking = false},
new Room {RoomNumber = "104", Beds = 2, RoomType = RoomTypeEnum.Double, Minibar = true, Occupied = false, Smoking = true},
new Room {RoomNumber = "105", Beds = 3, RoomType = RoomTypeEnum.Family, Minibar = true, Occupied = false, Smoking = false},
};
rooms.ForEach(b => context.Rooms.AddOrUpdate(b));
context.SaveChanges();
AddOrUpdateReservation(context, "101", "123456789");
context.SaveChanges();
}
void AddOrUpdateReservation(DataContext context, string roomNumber, string reservationNumber)
{
var reservation = context.Reservations.SingleOrDefault(c => c.ReservationNumber == reservationNumber);
var room = reservation.Room.SingleOrDefault(r => r.RoomNumber == roomNumber);
if (room == null)
reservation.Room.Add(context.Rooms.Single(i => i.RoomNumber == roomNumber));
}
的Reservation
表看起来不错,Rooms
表看起来不错,也和共享表ReservationRoom
看起来也不错。问题是ContactPerson
表,当我添加一个房间或预订时,它会在添加正确的联系人之前添加一个空行。
你看它这个截图:
在这里,你看到的结果只是运行命令,add-migration InitialCreate
和update-database
后。
这种尝试添加预约我在我的应用程序中创建时也会发生,使用该方法时:
public void CreateReservation(Reservation item)
{
Reservations.Add(item);
}
预约表是这样的:
在这里你可以看到它指向由于某种原因而创建的空的空行。
希望有人能告诉我这里可能是错的。我用了几天的时间试图重新配置模型和东西,但似乎没有人为我工作。
你有这样的问题,因为你的Reservation
构造函数实现是不正确:
public Reservation()
{
Room = new List<Room>();
ContactPerson = new ContactPerson();
}
实现这样,你会自动创建一个保留的新ContactPerson
。然后,在将Reservation
保存在您的Seed
方法中时,它将不会使用您在Seed
方法中创建的那一个ContactPerson
人。
构造函数改成这样:
public Reservation()
{
Room = new List<Room>();
}
然后在您的Seed
方法,因为每个Reservation
必须有一个ContactPerson
你应该插入ContactPerson
创建附加Reservation
这样前:
protected override void Seed(WebApplication1.DAL.DataContext context)
{
var contactPersons = new List<ContactPerson>
{
new ContactPerson{Title = "Mr" ,FirstName = "Anders",LastName = "Christensen", Email = "[email protected]", NationalityType = Nationality.Denmark, PhoneNumber = "44216731" }
};
contactPersons.ForEach(b => context.ContactPersons.AddOrUpdate(c => c.ContactPersonID, b));
context.SaveChanges();
var reservations = new List<Reservation>
{
new Reservation{ReservationNumber = "123456789", CheckInDate = DateTime.Parse("2016-01-01"), CheckOutDate = DateTime.Parse("2016.01.15"), ContactPersonID = 1
}
};
reservations.ForEach(b => context.Reservations.AddOrUpdate(r => r.ReservationID, b));
context.SaveChanges();
var rooms = new List<Room>
{
new Room {RoomNumber = "101", Beds = 1, RoomType = RoomTypeEnum.Single, Minibar = true, Occupied = true, Smoking = false},
new Room {RoomNumber = "102", Beds = 1, RoomType = RoomTypeEnum.Single, Minibar = true, Occupied = true, Smoking = false},
new Room {RoomNumber = "103", Beds = 1, RoomType = RoomTypeEnum.Single, Minibar = true, Occupied = false, Smoking = false},
new Room {RoomNumber = "104", Beds = 2, RoomType = RoomTypeEnum.Double, Minibar = true, Occupied = false, Smoking = true},
new Room {RoomNumber = "105", Beds = 3, RoomType = RoomTypeEnum.Family, Minibar = true, Occupied = false, Smoking = false},
};
rooms.ForEach(b => context.Rooms.AddOrUpdate(b));
context.SaveChanges();
AddOrUpdateReservation(context, "101", "123456789");
context.SaveChanges();
}
我想你也可以在你的方法结束时调用SaveChanges
一次,但为了工作,你需要避免像你在做的那样使用常量外键。
嘿,谢谢你的回复。我正在尝试在我的应用程序中立即.. – Mikkel
最后它的工作原理!你该死。一直在2天内尝试找出造成这个问题的地方:D很多很多,谢谢你,先生和美好的一天。 – Mikkel