当添加测试数据(保留)时,实体框架在实际行之前添加一个空的空行

问题描述:

我有一个问题,即在向数据库添加保留或我的测试数据时(使用实体框架),它创建了一个空其中一个表中的空行。当添加测试数据(保留)时,实体框架在实际行之前添加一个空的空行

我有3个表

  • 预订
  • ContactPerson
  • 客房

有一个许多人ReservationRooms之间一对多的关系。 ContactPersonReservation之间有一对多关系。

我正在使用代码优先的方法。

预订类:

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表,当我添加一个房间或预订时,它会在添加正确的联系人之前添加一个空行。

你看它这个截图:

enter image description here

在这里,你看到的结果只是运行命令,add-migration InitialCreateupdate-database后。

这种尝试添加预约我在我的应用程序中创建时也会发生,使用该方法时:

public void CreateReservation(Reservation item) 
{ 
    Reservations.Add(item); 
} 

预约表是这样的:

enter image description here

在这里你可以看到它指向由于某种原因而创建的空的空行。

希望有人能告诉我这里可能是错的。我用了几天的时间试图重新配置模型和东西,但似乎没有人为我工作。

你有这样的问题,因为你的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一次,但为了工作,你需要避免像你在做的那样使用常量外键。

+0

嘿,谢谢你的回复。我正在尝试在我的应用程序中立即.. – Mikkel

+1

最后它的工作原理!你该死。一直在2天内尝试找出造成这个问题的地方:D很多很多,谢谢你,先生和美好的一天。 – Mikkel