实体框架:将实体添加到数据库跳过添加到特定表

时间:2016-04-20 16:00:21

标签: c# database entity-framework entity-framework-6

我整天都在试图找出我应该对这个问题做些什么。问题是当我添加"预订"使用EF将实体添加到数据库中,它会向我不需要的其中一个表添加不必要的内容。我不确定它的数据模型是否会导致问题。

创建了一个如下所示的数据模型:

enter image description here

预订和房间之间有很多关系。许多预订应仅限1位联系人。

我的模特看起来像这样:

预订 :(遗漏了不必要的属性)

public class Reservation
{
    public int ReservationID { get; set; }
    public int ContactPersonID { get; set; }

    public virtual ContactPerson ContactPerson { get; set; }
    public virtual ICollection<Room> Room { get; set; }

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

房间 :(遗漏了不必要的属性)

public class Room
{
    public int ID { get; set; }
    public string RoomNumber { get; set; }

    public virtual ICollection<Reservation> Reservations { get; set; }
}

ContactPerson :(遗漏了不必要的属性)

public class ContactPerson
{
    public int ContactPersonID { get; set; }

    public virtual ICollection<Reservation> Reservations { get; set; }
}

然后我创建了一个DataContext类,如下所示:

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 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"));
    }
}

因为它是房间和预订之间的多对多关系,所以将创建一个共享表。

我为应用程序创建了一些测试数据,并使用迁移更新了数据库。 Room模型应在酒店中创建一个房间表,如下数据:

 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},             
        };

rooms.ForEach(b => context.Rooms.AddOrUpdate(b));
context.SaveChanges();

应用程序启动时应生成此测试数据。问题是,当我使用Reservations.Add中的DataContext添加预订时,它会向Room表添加新房间。

我想要的只是更新预订表,联系表和预订房间的共享表。

因此,如果预订有房间101(ID 1)和房间102(ID 2),则应在共享表内使用这些ID。

出于某种原因,当我添加预订并且预订有一个房间ID = 1(房间101)时,它会为此房间添加一个新生成的ID(ID = 5,因为表中已有4个房间)它不应该这样做。它还更新共享表并使用此ID = 5,它应该使用ID = 1。

试图尽可能地解释这个,希望有人能告诉我我的下一步行动。美好的一天:)

2 个答案:

答案 0 :(得分:0)

快速浏览一下,我注意到你的模型非常复杂。你真的从房间和客户导航属性到预订?

编写(添加,更新,删除)复杂对象图的操作是实体框架中的一个难点,尤其是当对象断开连接时。

简化您的模型并从房间和客户中删除ICollection预订。

向您的数据访问层添加其他方法,以便按房间和客户进行预订。

答案 1 :(得分:0)

发现导致问题的问题。正如Bernhard Kircher向我解释的那样,背景出现了问题。

通过获取所有房间的列表来解决问题,过滤它以便只有被选中的房间可以在列表中。

将该列表添加到预订中。一些它是如何工作的,所以我想有一些关于国家的事情。

public bool Execute(Reservation reservation)
    {
        //Add correct rooms to reservation;
        List<Room> roomsEntities = new List<Room>();

        foreach (var room in reservation.Room)
        {
            var roomsFound = _db.Rooms.Where(r => r.ID == room.ID).ToList();

            foreach (var ro in roomsFound)
            {
                roomsEntities.Add(ro);
            }
        }

        //Add correct rooms to entity.
        reservation.Room = roomsEntities;

        try
        {
            _db.CreateReservation(reservation);
            _db.SaveChanges();
        }
        catch (Exception e)
        {
            return false;
        }

        return true;
    }

为其他人添加了代码以便遇到同样的问题:)