Table Splitting Entity Framework Code First - 3+ Entities - c#

I've posted a question in Programmers: https://softwareengineering.stackexchange.com/questions/315857/entity-framework-code-first-c-class-separation-and-eav
One solution to the problem is Table Splitting in Entity Framework. So far, I've seen how to do this with 2 entities, but not with 3 or more.
Here are the models I want to share a same table with:
[Table("Tournament")]
public partial class PGTournament : IImageable
{
public int Id { get; set; }
public string Name { get; set; }
public GameGenre GameGenre { get; set; }
public TournamentFormat TournamentFormat { get; set; }
public TournamentStatus Status { get; set; }
public string Description { get; set; }
public virtual List<PrizePool> Prizes { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public virtual List<Participants.Participant> Participants { get; set; }
public decimal Cost { get; set; }
public string Streaming { get; set; }
public int? ChallongeTournamentId { get; set; }
public string Bracket { get; set; }
public virtual List<TournamentMatch> Matches { get; set; }
public int MainImageId { get; set; }
public virtual Media MainImage { get; set; }
public bool IsFollowUp { get; set; }
public int? FollowUpTournamentId { get; set; }
[ForeignKey("FollowUpTournamentId")]
public virtual PGTournament FollowUptournament { get; set; }
public int MediaID { get; set; }
public int MainImageID { get; set; }
//Properties that share same table:
public virtual TournamentOrganizer Organizer { get; set; } //Change to Organizer
public virtual TournamentOrganizerSetting OrganizerSetting { get; set; }
public virtual TournamentSettings TournamentSettings { get; set; }
public virtual TournamentRules Rules { get; set; }
}
All the properties you see that are virtual and don't have a List<> as their type, I want them to share a same table (If it is possible).
[Table("Tournament")]
public partial class TournamentOrganizer
{
public int Id { get; set; }
public string Name { get; set; }
public string UserId { get; set; }
[ForeignKey("UserId")]
public AppUser User { get; set; }
public int LogoId { get; set; }
[ForeignKey("LogoId")]
public Media Logo { get; set; }
public virtual TournamentOrganizerSetting Settings { get; set; }
public virtual TournamentRules Rules { get; set; }
public virtual TournamentSettings TournamentSettings { get; set; }
public virtual PGTournament Tournament { get; set; }
}
[Table("Tournament")]
public partial class TournamentSettings
{
public int Id { get; set; }
public string Address { get; set; }
public string LocationGoogleMaps { get; set; }
public bool isOnline { get; set; }
public int MaxPlayers { get; set; }
public List<TournamentAssistant> TournamentAssistants { get; set; }
public virtual TournamentOrganizer Organizer { get; set; } //Change to Organizer
public virtual TournamentRules Rules { get; set; }
public virtual TournamentOrganizerSetting OrganizerSettings { get; set; }
public virtual PGTournament Tournament { get; set; }
}
[Table("Tournament")]
public partial class TournamentOrganizerSetting
{
public int Id { get; set; }
public string Location { get; set; }
//Properties that share same table:
public virtual TournamentOrganizer Organizer { get; set; } //Change to Organizer
public virtual TournamentRules Rules { get; set; }
public virtual TournamentSettings TournamentSettings { get; set; }
public virtual PGTournament Tournament { get; set; }
}
[Table("Tournament")]
public partial class TournamentRules
{
public int Id { get; set; }
public string Bans { get; set; }
public string Allowed { get; set; }
public string Description { get; set; }
public string FileName { get; set; }
public string FilePath { get; set; }
//Properties that share same table:
public virtual TournamentOrganizer Organizer { get; set; } //Change to Organizer
public virtual TournamentOrganizerSetting OrganizerSetting { get; set; }
public virtual TournamentSettings TournamentSettings { get; set; }
public virtual PGTournament Tournament { get; set; }
}
I don't know why the classes are partial. I've been following several tutorials over the Internet, such as this: http://www.c-sharpcorner.com/UploadFile/ff2f08/table-splitting-in-entity-framework-6-code-first-approach/
I can't get them to work.
I have even tried this in the DbModelBuilder:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<PGTournament>().ToTable("Tournament");
modelBuilder.Entity<PGTournament>()
.HasKey(e => e.Id)
.HasOptional(e => e.FollowUptournament)
.WithMany();
modelBuilder.Entity<PGTournament>()
.HasKey(e => e.Id)
.HasRequired(e => e.Organizer)
.WithRequiredDependent(e => e.Organizer)
modelBuilder.Entity<TournamentOrganizer>()
.HasKey(e => e.Id)
.HasRequired(e => e.Settings)
.WithRequiredDependent(e => e.Organizer);
modelBuilder.Entity<TournamentViewModel>()
.HasKey(e => e.Id)
.HasRequired(e => e.Settings)
.WithRequiredDependent(e => e.Organizer);
modelBuilder.Entity<TournamentOrganizer>().Map(m => m.ToTable("Tournament"));
modelBuilder.Entity<TournamentOrganizerSetting>().Map(m => m.ToTable("Tournament"));
base.OnModelCreating(modelBuilder);
}
There doesn't seem to be a StackOverflow post with Mapping to 3 or more entities.
When I try to run it, this is the error I get:
One or more validation errors were detected during model generation:
Pro_Gaming.Infrastructure.IdentityUserLogin: : EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType.
Pro_Gaming.Infrastructure.IdentityUserRole: : EntityType 'IdentityUserRole' has no key defined. Define the key for this EntityType.
IdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins' is based on type 'IdentityUserLogin' that has no keys defined.
IdentityUserRoles: EntityType: EntitySet 'IdentityUserRoles' is based on type 'IdentityUserRole' that has no keys defined.

This answer comes from Cole Wu from ASP.NET forums:
http://forums.asp.net/p/2093110/6043922.aspx?p=True&t=635968548324560382
The answer is the following:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Do not delete this:
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Tournament>()
.HasKey(e => e.TournamentId)
.HasRequired(e => e.Rules)
.WithRequiredPrincipal();
modelBuilder.Entity<Tournament>()
.HasKey(e => e.TournamentId)
.HasRequired(e => e.TournamentSettings)
.WithRequiredDependent();
modelBuilder.Entity<TournamentOrganizer>()
.HasKey(e => e.Id)
.HasRequired(e => e.Settings)
.WithRequiredDependent();
modelBuilder.Entity<Tournament>().ToTable("Tournament");
modelBuilder.Entity<TournamentRules>().ToTable("Tournament");
modelBuilder.Entity<TournamentSettings>().ToTable("Tournament");
modelBuilder.Entity<TournamentOrganizer>().ToTable("TournamentOrganizer");
modelBuilder.Entity<TournamentOrganizerSetting>().ToTable("TournamentOrganizer");
}
Explaining a bit:
There is no need for partial classes (I say this because there is an
example that states that you need partial classes, this is not
true):
I haven't tested this, but I used the same key for all the classes that I wanted to share the same table.
modelBuilder.Entity <= TheEntity will be the main class you want everything mapped to.
If you are using ASP.NET Identity and you are extending from IdentityDbContext (which is my case), It is very important
to include base.OnModelCreating(modelBuilder) in the OnModelCreating method, otherwise you'll be hit with Identityissues that it doesn't find the primary key for IdenittyUser.
You would then use:
modelBuilder.Entity.ToTable("MyTable")
modelBuilder.Entity.ToTable("MyTable")
modelBuilder.Entity.ToTable("MyTable")
This will map Entity1, Entity2, Entity3, etc to MyTable.

Related

2 Foreign Keys pointing to the same table [duplicate]

I've just started using EF code first, so I'm a total beginner in this topic.
I wanted to create relations between Teams and Matches:
1 match = 2 teams (home, guest) and result.
I thought it's easy to create such a model, so I started coding:
public class Team
{
[Key]
public int TeamId { get; set;}
public string Name { get; set; }
public virtual ICollection<Match> Matches { get; set; }
}
public class Match
{
[Key]
public int MatchId { get; set; }
[ForeignKey("HomeTeam"), Column(Order = 0)]
public int HomeTeamId { get; set; }
[ForeignKey("GuestTeam"), Column(Order = 1)]
public int GuestTeamId { get; set; }
public float HomePoints { get; set; }
public float GuestPoints { get; set; }
public DateTime Date { get; set; }
public virtual Team HomeTeam { get; set; }
public virtual Team GuestTeam { get; set; }
}
And I get an exception:
The referential relationship will result in a cyclical reference that is not allowed. [ Constraint name = Match_GuestTeam ]
How can I create such a model, with 2 foreign keys to the same table?
Try this:
public class Team
{
public int TeamId { get; set;}
public string Name { get; set; }
public virtual ICollection<Match> HomeMatches { get; set; }
public virtual ICollection<Match> AwayMatches { get; set; }
}
public class Match
{
public int MatchId { get; set; }
public int HomeTeamId { get; set; }
public int GuestTeamId { get; set; }
public float HomePoints { get; set; }
public float GuestPoints { get; set; }
public DateTime Date { get; set; }
public virtual Team HomeTeam { get; set; }
public virtual Team GuestTeam { get; set; }
}
public class Context : DbContext
{
...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Match>()
.HasRequired(m => m.HomeTeam)
.WithMany(t => t.HomeMatches)
.HasForeignKey(m => m.HomeTeamId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Match>()
.HasRequired(m => m.GuestTeam)
.WithMany(t => t.AwayMatches)
.HasForeignKey(m => m.GuestTeamId)
.WillCascadeOnDelete(false);
}
}
Primary keys are mapped by default convention. Team must have two collection of matches. You can't have single collection referenced by two FKs. Match is mapped without cascading delete because it doesn't work in these self referencing many-to-many.
It's also possible to specify the ForeignKey() attribute on the navigation property:
[ForeignKey("HomeTeamID")]
public virtual Team HomeTeam { get; set; }
[ForeignKey("GuestTeamID")]
public virtual Team GuestTeam { get; set; }
That way you don't need to add any code to the OnModelCreate method
I know it's a several years old post and you may solve your problem with above solution. However, i just want to suggest using InverseProperty for someone who still need. At least you don't need to change anything in OnModelCreating.
The below code is un-tested.
public class Team
{
[Key]
public int TeamId { get; set;}
public string Name { get; set; }
[InverseProperty("HomeTeam")]
public virtual ICollection<Match> HomeMatches { get; set; }
[InverseProperty("GuestTeam")]
public virtual ICollection<Match> GuestMatches { get; set; }
}
public class Match
{
[Key]
public int MatchId { get; set; }
public float HomePoints { get; set; }
public float GuestPoints { get; set; }
public DateTime Date { get; set; }
public virtual Team HomeTeam { get; set; }
public virtual Team GuestTeam { get; set; }
}
You can read more about InverseProperty on MSDN: https://msdn.microsoft.com/en-us/data/jj591583?f=255&MSPPError=-2147217396#Relationships
You can try this too:
public class Match
{
[Key]
public int MatchId { get; set; }
[ForeignKey("HomeTeam"), Column(Order = 0)]
public int? HomeTeamId { get; set; }
[ForeignKey("GuestTeam"), Column(Order = 1)]
public int? GuestTeamId { get; set; }
public float HomePoints { get; set; }
public float GuestPoints { get; set; }
public DateTime Date { get; set; }
public virtual Team HomeTeam { get; set; }
public virtual Team GuestTeam { get; set; }
}
When you make a FK column allow NULLS, you are breaking the cycle. Or we are just cheating the EF schema generator.
In my case, this simple modification solve the problem.
InverseProperty in EF Core makes the solution easy and clean.
InverseProperty
So the desired solution would be:
public class Team
{
[Key]
public int TeamId { get; set;}
public string Name { get; set; }
[InverseProperty(nameof(Match.HomeTeam))]
public ICollection<Match> HomeMatches{ get; set; }
[InverseProperty(nameof(Match.GuestTeam))]
public ICollection<Match> AwayMatches{ get; set; }
}
public class Match
{
[Key]
public int MatchId { get; set; }
[ForeignKey(nameof(HomeTeam)), Column(Order = 0)]
public int HomeTeamId { get; set; }
[ForeignKey(nameof(GuestTeam)), Column(Order = 1)]
public int GuestTeamId { get; set; }
public float HomePoints { get; set; }
public float GuestPoints { get; set; }
public DateTime Date { get; set; }
public Team HomeTeam { get; set; }
public Team GuestTeam { get; set; }
}
This is because Cascade Deletes are enabled by default. The problem is that when you call a delete on the entity, it will delete each of the f-key referenced entities as well. You should not make 'required' values nullable to fix this problem. A better option would be to remove EF Code First's Cascade delete convention:
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
It's probably safer to explicitly indicate when to do a cascade delete for each of the children when mapping/config. the entity.
I know this is pretty old question but coming here in 2021 with EF Core > 3 solution below worked for me.
Make sure to make foreign keys nullable
Specify default behavior on Delete
public class Match
{
public int? HomeTeamId { get; set; }
public int? GuestTeamId { get; set; }
public float HomePoints { get; set; }
public float GuestPoints { get; set; }
public DateTime Date { get; set; }
public Team HomeTeam { get; set; }
public Team GuestTeam { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Match>()
.HasRequired(m => m.HomeTeam)
.WithMany(t => t.HomeMatches)
.HasForeignKey(m => m.HomeTeamId)
.OnDelete(DeleteBehavior.ClientSetNull);
modelBuilder.Entity<Match>()
.HasRequired(m => m.GuestTeam)
.WithMany(t => t.AwayMatches)
.HasForeignKey(m => m.GuestTeamId)
.OnDelete(DeleteBehavior.ClientSetNull);
}

asp.net mvc (Migration)

I crete table in asp.net mvc but when i crete the migration this error message show
Introducing FOREIGN KEY constraint 'FK_dbo.DailyTransactions_dbo.Contracts_ContractId' on table 'DailyTransactions' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.
this is DailyTransactions table :
public class DailyTransactions
{
[Key]
public int DailyTransactions_Id { get; set; }
public double Account { get; set; }
public string Account_Name { get; set; }
public double Debit { get; set; }
public double Credit { get; set; }
public DateTime Date { get; set; }
public string Remarks { get; set; }
public int CustomerId { get; set; }
[ForeignKey("CustomerId")]
public virtual Customers customers { get; set; }
public int ContractId { get; set; }
[ForeignKey("ContractId")]
public virtual Contracts contracts { get; set; }
}
and this contract table :
public class Contracts
{
[Key]
public int Contracts_Id { get; set; }
public int Contract_Num { get; set; }
public DateTime Contract_Start { get; set; }
public DateTime Contract_End { get; set; }
public string Status { get; set; }
public string TypeOfRent { get; set; }
public double AmountOfRent { get; set; }
public double Total { get; set; }
public int CustomerId { get; set; }
[ForeignKey("CustomerId")]
public virtual Customers customers { get; set; }
public int sectionsId { get; set; }
[ForeignKey("sectionsId")]
public virtual Sections sections { get; set; }
}
Try to turn off CascadeDelete for DailyTransactions and Contracts:
modelBuilder.Entity<DailyTransactions>()
.HasRequired(c => c.Contracts)
.WithMany()
.WillCascadeOnDelete(false);
For example:
public class YourDBContext: DbContext
{
public YourDBContext(): base()
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<DailyTransactions>()
.HasRequired(c => c.Contracts)
.WithMany()
.WillCascadeOnDelete(false);
}
}

EF Core self referencing many to many

I have User table and I'd like to add connection called UserFriend between 2 users. I've searched a lot and basicly tried many different solutions and none of them worked. Everytime I get same error:
Introducing FOREIGN KEY constraint 'FK_UserFriends_Users_Friend2Id' on table 'UserFriends' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Here are my models:
public class User
{
[Key]
public Guid Id { get; set; }
public string Username { get; set; }
public string EmailAddress { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public virtual ICollection<UserFriend> Friends { get; set; }
public virtual ICollection<UserFriend> FriendOf { get; set; }
}
public class UserFriend
{
public User Friend1 { get; set; }
public Guid Friend1Id { get; set; }
public User Friend2 { get; set; }
public Guid Friend2Id { get; set; }
public bool Confirmed { get; set; }
public DateTime Added { get; set; }
}
And here's code in DataContext:
modelBuilder.Entity<UserFriend>().HasKey(sc => new { sc.Friend1Id, sc.Friend2Id });
modelBuilder.Entity<UserFriend>()
.HasOne(c => c.Friend1)
.WithMany(c => c.FriendOf)
.HasForeignKey(f => f.Friend1Id);
modelBuilder.Entity<UserFriend>()
.HasOne(c => c.Friend2)
.WithMany(c => c.Friends)
.HasForeignKey(f => f.Friend2Id)
.OnDelete(DeleteBehavior.Restrict);
Change your code to below and remove the other lines you have posted.
public class User
{
[Key]
public Guid Id { get; set; }
public string Username { get; set; }
public string EmailAddress { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public virtual ICollection<UserFriend> Friends { get; set; }
public virtual ICollection<UserFriend> FriendOf { get; set; }
}
public class UserFriend
{
public User Friend1 { get; set; }
[ForeignKey("Friend1")]
public Guid? Friend1Id { get; set; }
public User Friend2 { get; set; }
[ForeignKey("Friend2")]
public Guid? Friend2Id { get; set; }
public bool Confirmed { get; set; }
public DateTime Added { get; set; }
}
modelBuilder.Entity<User>();
modelBuilder.Entity<UserFriend>();

Entity Framework not creating extra columns in join table

Can somebody explain why Entity Framework will not create extra columns CurVal and NewVal in join table? It is creating a join table with DeviceFeatureID and UserDeviceID.
public class DeviceFeature
{
[Display(Name = "ID")]
public int DeviceFeatureID { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<DeviceType> DeviceTypes { get; set; }
public virtual ICollection<UserDevice> UserDevices { get; set; }
}
public class UserDevice
{
public int UserDeviceID { get; set; }
public int DeviceTypeID { get; set; }
public string UserID { get; set; }
public string DeviceName { get; set;}
public virtual ICollection<DeviceFeature> DeviceFeatures { get; set; }
}
public class UserDeviceFeatureStatus
{
public int UserDeviceID { get; set; }
public int DeviceFeatureID { get; set; }
public virtual UserDevice UserDevice { get; set; }
public virtual DeviceFeature DeviceFeature { get; set; }
public string CurVal { get; set; }
public string NewVal { get; set; }
}
Your many-to-many relationship table is being generated automatically by your Virtual Collections an not by your entity.
You can either include the join entity in the DbContext (but it will probably duplicate the table unless you remove the virtual collections) or you can use the Fluent API to configure the relationship.
To do the later you will need to change your Virtual Collections to the ReleationShip type and add this to your OnModelCreating:
modelBuilder.Entity<UserDeviceFeatureStatus>()
.HasKey(t => new { t.UserDeviceID, t.DeviceFeatureID });
modelBuilder.Entity<UserDeviceFeatureStatus>()
.HasOne(pt => pt.UserDevice)
.WithMany(p => p.DeviceFeatures) // from UserDevice
.HasForeignKey(pt => pt.UserDeviceID);
modelBuilder.Entity<UserDeviceFeatureStatus>()
.HasOne(pt => pt.DeviceFeature)
.WithMany(t => t.UserDevices) //from DeviceFeature
.HasForeignKey(pt => pt.DeviceFeatureID);
In DeviceFeature
public virtual ICollection<UserDeviceFeatureStatus> UserDevices { get; set; }
In UserDevice
public virtual ICollection<UserDeviceFeatureStatus> DeviceFeatures { get; set; }
For more information about EF relationships you can see the docs here.
If you want to make a many-to-many relationship between UserDevice and DeviceFeature through UserDeviceFeatureStatus than you need to have a navigation property from the 2 tables to your "join" table. I understand that you try to navigate directly from UserDevice to DeviceFeature directly and vice-versa. But you won't be able to do that in EF if your relationship table contains other fields than the primary keys of the tables you're trying to link.
You can try this:
public class DeviceFeature
{
[Display(Name = "ID")]
public int DeviceFeatureID { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<DeviceType> DeviceTypes { get; set; }
public virtual ICollection<UserDeviceFeatureStatus> UserDeviceFeatureStatuses { get; set; }
}
public class UserDevice
{
public int UserDeviceID { get; set; }
public int DeviceTypeID { get; set; }
public string UserID { get; set; }
public string DeviceName { get; set;}
public virtual ICollection<UserDeviceFeatureStatus> UserDeviceFeatureStatuses { get; set; }
}
public class UserDeviceFeatureStatus
{
public int UserDeviceID { get; set; }
public int DeviceFeatureID { get; set; }
public virtual UserDevice UserDevice { get; set; }
public virtual DeviceFeature DeviceFeature { get; set; }
public string CurVal { get; set; }
public string NewVal { get; set; }
}
So to navigate from UserDevice to DeviceFeature for example, you'll need to navigate to UserDeviceFeatureStatus first then from there to DeviceFeature.

Defining many to many relation in code first entity framework

I have 3 classes in my model as you can see below.
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string UserName { get; set; }
public ICollection<MartialArtUserProfile> MartialArtUserProfiles { get; set; }
}
[Table("MartialArt")]
public class MartialArt
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string IconPath { get; set; }
public string ImagePath { get; set; }
public ICollection<MartialArtUserProfile> MartialArtUserProfiles { get; set; }
}
public class MartialArtUserProfile
{
public int UserProfileId { get; set; }
public UserProfile UserProfile { get; set; }
public int MartialArtId { get; set; }
public MartialArt MartialArt { get; set; }
}
And I have a configuration class for many to many relationship as below:
public class MartialArtUserProfileConfiguration : EntityTypeConfiguration<MartialArtUserProfile>
{
public MartialArtUserProfileConfiguration()
{
HasKey(a => new { a.MartialArtId, a.UserProfileId });
HasRequired(a => a.MartialArt)
.WithMany(s => s.MartialArtUserProfiles)
.HasForeignKey(a => a.MartialArtId)
.WillCascadeOnDelete(false);
HasRequired(a => a.UserProfile)
.WithMany(p => p.MartialArtUserProfiles)
.HasForeignKey(a => a.UserProfileId)
.WillCascadeOnDelete(false);
}
}
After defining my entities an relation when I try to run Update-Database in Package Manager Console, it says:
One or more validation errors were detected during model generation:
\tSystem.Data.Entity.Edm.EdmEntityType: : EntityType 'MartialArtUserProfile' has no key defined. Define the key for this EntityType.
\tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'MartialArtUserProfiles' is based on type 'MartialArtUserProfile' that has no keys defined.
What am I doing wrong?
Thanks in advance,
If I understand you are simply trying to create a many to many with a transitive table. If so this is another way to approach this. Use Fluent API to map as below. You can change the UserProfileToMartialArt to whatever you want the table name to be. Instead of creating the MartialArtUserProfile model let EF create the middle ground for you. This also specifies your keys which should get you around the error.
modelBuilder.Entity<UserProfile>()
.HasMany(b => b.MartialArts)
.WithMany(a => a.UserProfiles)
.Map(m => m.MapLeftKey("MartialArtId")
.MapRightKey("UserProfileId")
.ToTable("UserProfileToMartialArt"));
In MartialArts Model put
public IList<UserProfile> UserProfiles { get; set; }
In UserProfile Model put
public IList<MartialArt> MartialArts { get; set; }
Try doing it like this:
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string UserName { get; set; }
[InverseProperty("UserProfiles")]
public IList<MartialArt> MartialArts { get; set; }
}
[Table("MartialArt")]
public class MartialArt
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string IconPath { get; set; }
public string ImagePath { get; set; }
[InverseProperty("MartialArts")]
public IList<UserProfile> UserProfiles { get; set; }
}
In EntityFramework 6.1, you don't need to do any of this - just add collections of the two types to each class and everything falls into place.
public class UserProfile {
public int Id { get; set; }
public string UserName { get; set; }
public virtual ICollection<MartialArt> MartialArts { get; set; }
public UserProfile() {
MartialArts = new List<MartialArt>();
}
}
public class MartialArt {
public int Id { get; set; }
public string Name { get; set; }
// *snip*
public virtual ICollection<UserProfile> UserProfiles { get; set; }
public MartialArt() {
UserProfiles = new List<UserProfile>();
}
}

Categories

Resources