Code First CTP5 Many To Many Binding
I have been using the Code First approach for the Entity Framework. I have an Event class, a Band class and a EventBands class which maps the many to many relationship. The Code First approach worked fine (When I didn't have the EventBands class) but then I decided I wanted the many to many table to store additional values. Now I get this error message:
System.Data.Edm.EdmEntityType: : EntityType 'EventBands' has no key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntitySet: EntityType: The EntitySet EventBands is based on type EventBands that has no keys defined.
It obvious what the error message means. However the resolution isn't so obvious. I think I have to override the model binding method but I am not entirely sure how to map keys with this approach.
Any help would be appreciated, I have included the classes in question below.
Thanks in advance,
Jon
Event:
#region Properties
private int eventId;
public int EventId
{
get
{
return eventId;
}
set
{
eventId = value;
}
}
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
private string description;
开发者_Python百科 public string Description
{
get
{
return description;
}
set
{
description = value;
}
}
private DateTime startDatetime;
public DateTime StartDateTime
{
get
{
return startDatetime;
}
set
{
startDatetime = value;
}
}
private DateTime endDatetime;
public DateTime EndDateTime
{
get
{
return endDatetime;
}
set
{
endDatetime = value;
}
}
private int venueUserId;
public int VenueUserId
{
get { return venueUserId; }
set { venueUserId = value; }
}
public virtual Venue Venue
{
get;
set;
}
public virtual ICollection<EventReview> Reviews
{
get;
set;
}
public virtual ICollection<EventBands> EventBands
{
get;
set;
}
public virtual ICollection<Fan> Attendees
{
get;
set;
}
#endregion
#region Constructor
public Event()
{
EventBands = new HashSet<EventBands>();
Attendees = new HashSet<Fan>();
StartDateTime = DateTime.Now;
EndDateTime = DateTime.Now.AddDays(14);
}
#endregion
Band:
public class Band : PostableUser
{
#region Properties
private int genreGenreId;
public int GenreGenreId
{
get { return genreGenreId; }
set { genreGenreId = value; }
}
public virtual Genre Genre
{
get;
set;
}
public virtual ICollection<Album> Albums
{
get;
set;
}
public virtual ICollection<BandReview> Reviews
{
get;
set;
}
public virtual ICollection<EventBands> EventBands
{
get;
set;
}
#endregion
#region Constructor
public Band()
{
EventBands = new HashSet<EventBands>();
}
#endregion
}
EventBands
#region Properties
private int eventEventId;
public int EventEventId
{
get { return eventEventId; }
set { eventEventId = value; }
}
public virtual Event Event
{
get;
set;
}
private int bandUserId;
public int BandUserId
{
get { return bandUserId; }
set { bandUserId = value; }
}
public virtual Band Band
{
get;
set;
}
private DateTime startDateTime;
public DateTime StartDateTime
{
get { return startDateTime; }
set { startDateTime = value; }
}
private DateTime endDateTime;
public DateTime EndDateTime
{
get { return endDateTime; }
set { endDateTime = value; }
}
#endregion
BandUserId is inherited from the User base class.
I got this working in the end by overriding the OnModelCreating method in my DataContext class.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new AlbumConfiguration());
modelBuilder.Configurations.Add(new BandConfiguration());
modelBuilder.Configurations.Add(new CityConfiguration());
modelBuilder.Configurations.Add(new CommentConfiguration());
modelBuilder.Configurations.Add(new CountryConfiguration());
modelBuilder.Configurations.Add(new CountyConfiguration());
modelBuilder.Configurations.Add(new EventBandsConfiguration());
modelBuilder.Configurations.Add(new EventFansConfiguration());
modelBuilder.Configurations.Add(new EventConfiguration());
modelBuilder.Configurations.Add(new FanConfiguration());
modelBuilder.Configurations.Add(new GenreConfiguration());
modelBuilder.Configurations.Add(new PostConfiguration());
modelBuilder.Configurations.Add(new RecordLabelConfiguration());
modelBuilder.Configurations.Add(new ReviewConfiguration());
modelBuilder.Configurations.Add(new TrackConfiguration());
modelBuilder.Configurations.Add(new UserConfiguration());
modelBuilder.Configurations.Add(new VenueConfiguration());
}
The Configuration classes contain the mappings of the primary, composite keys, foreign keys, and any other properties.
Event Configuration:
public class EventConfiguration : EntityTypeConfiguration<Event>
{
public EventConfiguration()
{
#region Primary Key
this.HasKey(x => x.EventId);
#endregion
#region Foreign Keys
this.HasRequired(x => x.Venue)
.WithMany()
.HasForeignKey(x => x.VenueId)
.WillCascadeOnDelete(false);
#endregion
#region Properties
this.Property(x => x.Description).IsRequired().HasColumnType("nvarchar");
this.Property(x => x.EndDateTime).IsRequired();
this.Property(x => x.Name).IsRequired().HasColumnType("nvarchar");
this.Property(x => x.StartDateTime).IsRequired();
#endregion
}
}
Event Bands Configuration:
public class EventBandsConfiguration : EntityTypeConfiguration<EventBands>
{
public EventBandsConfiguration()
{
#region Primary Key
this.HasKey(x => new { x.BandId, x.EventId });
#endregion
#region Foreign Keys
this.HasRequired(x => x.Band)
.WithMany()
.HasForeignKey(x => x.BandId)
.WillCascadeOnDelete(false);
this.HasRequired(x => x.Event)
.WithMany()
.HasForeignKey(x => x.EventId)
.WillCascadeOnDelete(false);
#endregion
#region Properties
this.Property(x => x.StartDateTime).IsRequired();
this.Property(x => x.EndDateTime).IsRequired();
#endregion
}
}
User Configuration:
public UserConfiguration()
{
#region Primary Key
this.HasKey(x => x.UserId);
#endregion
#region Foreign Keys
this.HasRequired(x => x.City)
.WithMany()
.HasForeignKey(x => x.CityId)
.WillCascadeOnDelete(false);
#endregion
#region Properties
this.Property(x => x.UserName);
this.Property(x => x.LoweredUserName);
this.Property(x => x.ApplicationName);
this.Property(x => x.Email);
this.Property(x => x.Comment);
this.Property(x => x.Password);
this.Property(x => x.PasswordQuestion);
this.Property(x => x.PasswordAnswer);
this.Property(x => x.IsApproved);
this.Property(x => x.LastActivityDate);
this.Property(x => x.LastLoginDate);
this.Property(x => x.LastPasswordChangedDate);
this.Property(x => x.CreationDate);
this.Property(x => x.IsOnline);
this.Property(x => x.IsLockedOut);
this.Property(x => x.LastLockedOutDate);
this.Property(x => x.FailedPasswordAttemptCount);
this.Property(x => x.FailedPasswordAttemptWindowStart);
this.Property(x => x.FailedPasswordAnswerAttemptCount);
this.Property(x => x.FailedPasswordAnswerAttemptWindowStart);
this.Property(x => x.MobileAlias);
this.Property(x => x.IsAnonymous);
this.Property(x => x.Description);
this.Property(x => x.Website);
#endregion
#region Inheritance Mapping
this.Map<Fan>(x => x.Requires("UserType").HasValue("Fan"))
.Map<Band>(x => x.Requires("UserType").HasValue("Band"))
.Map<Venue>(x => x.Requires("UserType").HasValue("Venue"));
#endregion
}
}
Band Configuration
public class BandConfiguration : EntityTypeConfiguration<Band>
{
public BandConfiguration()
{
#region Foreign Keys
this.HasRequired(x => x.Genre)
.WithMany()
.HasForeignKey(x => x.GenreId)
.WillCascadeOnDelete(false);
#endregion
}
}
精彩评论