Entity with many-to-many relationship creation fails after upgrading to RC
I've got a project with 3 simple tables, a couple of POCO classes, and a DBContext created with code, no edml file. The following code setup used to work with the beta of Entity Framework code-first, I've edited the DbContext code since the ModelBuilder changed from the beta to RC
Tables (simple tables many-to-many table has fields declared as foreign keys with cascade deletion):
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; }
}
DB Context
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"));
}
}
Creating a Booking (the bookingCarrrier is a helper class delivered by frontend layer)
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
};
}
When executing this code, EF throws a SqlException with the following message:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_UnitBookings_Units". The conflict occurred in database "grashult.dk", table "dbo.Units", column 'ID'.
Which wasn't the case in the beta.
I know t开发者_开发百科his is a fairly simplistic setup, but since this a hobby project, and I'm trying it out to see how simple a thing like this can be done.
Are anybody aware of changes that causes this behaviour? Is something like this still possible with EF 4.1, or do I have to whip out the data model designer?
Regards Jesper Hauge
You must swap your key mapping:
modelBuilder.Entity<Unit>()
.HasMany(u => u.Bookings)
.WithMany(b => b.Units)
.Map(m => m.MapLeftKey("UnitId")
.MapRightKey("BookingId")
.ToTable("UnitBookings"));
I just tested it and the problem was that Booking.Id
was stored in UnitId
and UnitId
in Booking.Id
.
精彩评论