在添加测试数据(保留)

时间:2016-04-30 07:42:49

标签: entity-framework ef-code-first ef-migrations

我遇到的问题是,在向数据库添加预留或我的测试数据时(使用Entity Framework),它在其中一个表中创建了一个空的空行。

我有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 = "AndersChristensen@gmail.com", 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

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

希望有人可以告诉我这里可能有什么问题。我用了很多天试图重新配置模型和东西,但似乎没有一个对我有效。

1 个答案:

答案 0 :(得分:1)

您遇到此类问题,因为您的Reservation构造函数实现不正确:

public Reservation()
{
    Room = new List<Room>();
    ContactPerson = new ContactPerson();
}

如此实施,您可以自动为预订创建新的ContactPerson。然后,在Reservation方法中保存Seed时,它将不会使用您在ContactPerson方法中创建的Seed人。

将构造函数更改为:

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 = "AndersChristensen@gmail.com", 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一次,但要实现这一点,您需要避免使用像您一样的常量外键。