Many to Many relationships and EF6.1 Code First

Posts   
 
    
fpdave100
User
Posts: 97
Joined: 06-Feb-2012
# Posted on: 22-Dec-2015 17:09:35   

Hi

I defined 2 entities (meeting and user), and wanted to specify a many to many between them.

I defined an entity MeetingAttendee, and a relationship 1:m to user and also a relationship 1:m to meeting.

I then specified a M:N relationship in the designer.

The designer didnt output a mapping method for the relationshiptable (MeetingAttendee), and when I came to insert a meeting I could do the following:

var mt = new Meeting();
mt.Attendees.Add(user1);
mt.Attendees.Add(user2);
dbcontext.Meetings.Add(mt);
dbcontext.SAveChanges()

and it gave the error

Invalid column name 'User_Id'. Invalid column name 'Meeting_Id'.

How much of this is expected?

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 22-Dec-2015 17:59:13   

Designer version (release date)?

Quoting the Designer docs:

On the Entity Framework and NHibernate the LLBLGen Pro designer only supports 'pure' many to many relationships, where the intermediate entity only consists of foreign key fields.

If you define a non-pure many to many relationship while having one of these target frameworks as the target framework of your project, they're ignored.

Is this a pure m:n relationship? Does the intermediate entity have other fields than the FKs?

fpdave100
User
Posts: 97
Joined: 06-Feb-2012
# Posted on: 22-Dec-2015 18:04:40   

No, just 2 FKs.

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 22-Dec-2015 19:43:13   

Please provide a repro LLBLGen project file.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39873
Joined: 17-Aug-2003
# Posted on: 23-Dec-2015 10:57:08   

fpdave100 wrote:

Hi

I defined 2 entities (meeting and user), and wanted to specify a many to many between them.

I defined an entity MeetingAttendee, and a relationship 1:m to user and also a relationship 1:m to meeting.

I then specified a M:N relationship in the designer.

The designer didnt output a mapping method for the relationshiptable (MeetingAttendee),

This is expected, as EF doesn't support objectified m:n relationships (i.e. a m:n relationship with an intermediate entity which is visible), it only supports m:n relationships with hidden intermediate entities.

and when I came to insert a meeting I could do the following:

var mt = new Meeting();
mt.Attendees.Add(user1);
mt.Attendees.Add(user2);
dbcontext.Meetings.Add(mt);
dbcontext.SAveChanges()

and it gave the error

Invalid column name 'User_Id'. Invalid column name 'Meeting_Id'.

How much of this is expected?

Hmmm. It does perform an insert on the intermediate table? (If you don't have orm profiler, please use the sqlserver profiler to see what queries are executed).

Frans Bouma | Lead developer LLBLGen Pro
fpdave100
User
Posts: 97
Joined: 06-Feb-2012
# Posted on: 23-Dec-2015 11:30:13   

it got the wrong columns names (compared to what the llblgen project specified) (should have been no underscores, ie UserId and MeetingId)

so, it did try to write it.

This is the only mapping is created:

        protected virtual void MapUser(EntityTypeConfiguration<User> config)
        {
            config.ToTable("User");
            config.HasKey(t => t.Id);
            config.Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
            config.HasRequired(t => t.ExternalUser).WithOptional(t => t.User);
            config.HasMany(t => t.MeetingsToAttend).WithMany(t => t.Attendees)
                    .Map(m =>
                    {
                        m.ToTable("MeetingAttendee");
                        m.MapLeftKey();
                        m.MapRightKey();
                    });
        }

and the entity itself:

public partial class MeetingAttendee: CommonEntityBase
    {

        public MeetingAttendee() : base()
        {
        }

        public System.Int32 MeetingId{ get; set;}
        public System.Guid UserId { get; set;}
        /// <summary>Represents the navigator which is mapped onto the association 'Events.MeetingAttendee.User - BasicEntities.User.Meetings(m:1)'</summary>
        public virtual User User { get; set;}
        /// <summary>Represents the navigator which is mapped onto the association 'Events.Meeting.Recipients - Events.MeetingAttendee.QDocDispatchEvent (1:n)'</summary>
        public virtual Meeting Meeting { get; set;}
    }

Note I have renamed the entities to keep it more obvious.

Did it just get the wrong feild names?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39873
Joined: 17-Aug-2003
# Posted on: 23-Dec-2015 11:44:46   

I think it's the MapLeftKey/MapRightKey methods which have empty constructor calls, but should get the names of the fields passed in.

In our tests we rely on the EF model verifier built into EF to verify whether what we generate is a correct model. It finds this a correct model and the mappings appear correct, but when you want to insert a m:n entity it indeed fails: the columns mapped are not found so it fabricates its own field names. As no key names are passed into the MapKeyLeft/MapKeyRight calls, it has to.

the template contains code to emit the names, however the output doesn't contain any output, so something's off.

Looking into it.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39873
Joined: 17-Aug-2003
# Posted on: 23-Dec-2015 11:54:27   

Found it. A recent fix in this template for the issue where it mapped FK fields even though they were PK fields causes this: the code re-uses a method to obtain FK fields to output but it skips PK fields if they're FK fields which is OK for all situations except for the m:n relationship where they always have to be emitted.

Working on fix.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39873
Joined: 17-Aug-2003
# Posted on: 23-Dec-2015 13:38:12   

Fixed. See attached template.

Attachments
Filename File size Added on Approval
codeFirstModelBuilder.lpt 17,928 23-Dec-2015 13:38.30 Approved
Frans Bouma | Lead developer LLBLGen Pro
fpdave100
User
Posts: 97
Joined: 06-Feb-2012
# Posted on: 23-Dec-2015 15:41:44   

wonderful support, as ever. Not at work today, but will try it later.