Сущность с созданием отношений «многие ко многим» завершается неудачно после обновления до RC - PullRequest
3 голосов
/ 05 апреля 2011

У меня есть проект с 3 простыми таблицами, парой классов POCO и DBContext, созданный с кодом, без файла edml.Следующая настройка кода, используемая для работы с бета-версией кода Entity Framework. Сначала я отредактировал код DbContext, так как ModelBuilder изменился с бета-версии на RC

Таблицы (простые таблицы «многие ко многим» имеют таблицу).поля, объявленные как внешние ключи с каскадным удалением):

CREATE TABLE [dbo].[Bookings](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [StartDate] [datetime] NOT NULL,
    [EndDate] [datetime] NOT NULL,
    [AccountId] [varchar](50) NOT NULL,
 CONSTRAINT [PK_Bookings] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)

CREATE TABLE [dbo].[Units](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](100) NOT NULL,
    [Description] [nvarchar](1000) NULL,
    [Beds] [int] NOT NULL,
 CONSTRAINT [PK_Units] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)

CREATE TABLE [dbo].[UnitBookings](
    [UnitId] [int] NOT NULL,
    [BookingId] [int] NOT NULL
) ON [PRIMARY]

POCOS:

public class Unit
{
    [Key]
    public int ID { get; set; }
    [Required]
    public string Name { get; set; }
    public string Description { get; set; }
    [Required]
    public int Beds { get; set; }
    public ICollection<Booking> Bookings { get; set; }
}

public class Booking
{
    [Key]
    public int ID { get; set; }
    [Required]
    public DateTime StartDate { get; set; }
    [Required]
    public DateTime EndDate { get; set; }
    [Required]
    public string AccountId { get; set; }
    public ICollection<Unit> Units { get; set; }
}

Контекст БД

public class BookingDb : DbContext
{
    public DbSet<Booking> Bookings { get; set; }
    public DbSet<Unit> Units { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Unit>()
            .HasMany(u => u.Bookings)
            .WithMany(b => b.Units)
            .Map(m => m.MapLeftKey("BookingId").MapRightKey("UnitId").ToTable("UnitBookings"));
    }
}

Создание бронирования (bookingCarrrier является помощникомкласс, предоставляемый внешним интерфейсом)

public static bool CreateBooking(BookingCarrier carrier, out string statusMsg)
{
    using (var db = new BookingDB())
    {
        var validator = new BookingValidator(2, 3);
        Booking booking = CreateBooking(carrier, db);
        if (validator.Validate(booking.AccountId, booking, -1, out statusMsg)
        {
            db.Bookings.Add(booking);
            db.SaveChanges();
            return true;
        }
        return false;
    }
}

private static CreateBooking(BookingCarrier carrier, BookingDB db)
{
    var units = new List<Unit>();
    if (carrier.SelectedUnit == 0)
        units.AddRange(db.Units.ToList());
    else
        units.Add(db.Units.Find(carrier.SelectedUnit));
    return new Booking
        {
            AccountId = carrier.AccountId,
            EndDate = carrier.EndDate,
            StartDate = carrier.StartDate,
            Units = units
        };
}

При выполнении этого кода EF создает исключение SqlException со следующим сообщением:

Оператор INSERT конфликтует с ограничением FOREIGN KEY "FK_UnitBookings_Units",Конфликт произошел в базе данных "grashult.dk", таблице "dbo.Units", столбце "ID".

Что не было в бета-версии.

Я знаю, что это довольно упрощенная установка, но, поскольку это хобби-проект, и я пытаюсь увидеть егокак просто сделать такую ​​вещь.

Кто-нибудь знает об изменениях, вызывающих такое поведение?Возможно ли что-то подобное с EF 4.1, или мне нужно выкрутить конструктор моделей данных?

С уважением, Джеспер Хауге

1 Ответ

7 голосов
/ 05 апреля 2011

Вы должны поменять местами сопоставление клавиш:

modelBuilder.Entity<Unit>()
            .HasMany(u => u.Bookings)
            .WithMany(b => b.Units)
            .Map(m => m.MapLeftKey("UnitId")
                       .MapRightKey("BookingId")
                       .ToTable("UnitBookings"));

Я только что проверил его, и проблема заключалась в том, что Booking.Id был сохранен в UnitId и UnitId в Booking.Id.

...