简体   繁体   中英

How to create many to many relation with EF when using generic

I have an abstract class called Entity which is defined as follow:

public abstract class Entity<T> : IEntity<T>
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public T Id { get; set; }
    ..
}

and here are a couple of data entity classes I'm using it with:

public class Company : Entity<Guid>
{
  ...
}

public class User : Entity<Guid>
{
  ...
}

By default, the Entity will provide an Id property of to both these classes, of type Guid in this instance, and I'm using configuration with fluent API for each to rename the Id property with a more relevant name when the relevant table is created. For example, for my company configuration

this.HasKey(u => u.Id)
   .Property(p => p.Id)
   .HasColumnName("CompanyId")
   .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

So far so good and everything is working as expected but my requirements have changed and I now need to create a many to many relationship between company and user, so I tried to define the relationship in my OnModelCreating method:

modelBuilder.Entity<Company>()
            .HasMany(s => s.Users)
            .WithMany(c => c.Companies)
            .Map(cs =>
            {
                cs.MapLeftKey("UserRefId");
                cs.MapRightKey("CompanyRefId");
                cs.ToTable("CompanyUsers");
            });

but when I try to update my database, I get the following error:

Schema specified is not valid. Errors: The relationship 'Data.Company_Users' was 
not loaded because the type 'Data.Company' is not available.

If I reverse the order:

modelBuilder.Entity<User>()
            .HasMany(s => s.Organizations)
            .WithMany(c => c.Users)
            .Map(cs =>
            {
                cs.MapLeftKey("OrganizationRefId");
                cs.MapRightKey("UserRefId");
                cs.ToTable("OrganizationUsers");
            });

I get the following error:

One or more validation errors were detected during model generation:

CompanyId: : There is no property with name 'CompanyId' defined in the type referred to by Role 'User_Companies_Target'. User_Companies_Source: : Multiplicity is not valid in Role 'User_Companies_Source' in relationship 'User_Companies'. Valid values for multiplicity for the Principal Role are '0..1' or '1'.

Any ideas how I can resolve this problem when my entities are inheriting from an abstract class and neither of them have the UserId or CompanyId defined in their respective class as both are inheriting the Id property from the abstract class and is only renamed when generating the table.

I hope the above makes sense. If not, let me know and I'll try to clarify.

Thanks

I eventually found out what the problem was: I stupidly left an existing foreign relationship already defined in both the User and Company Entities:

In the Company entity:

        this.HasMany(u => u.Users)
            .WithRequired(o => o.Company)
            .HasForeignKey(o => o.CompanyId);

In the User entity:

        this.HasRequired(u => u.Company)
            .WithMany(u => u.Users)
            .HasForeignKey(s => s.CompanyId);

Once I removed these and used:

modelBuilder.Entity<User>()
    .HasMany(s => s.Companies)
    .WithMany(c => c.Users)
    .Map(cs =>
    {
        cs.MapLeftKey("CompanyRefId");
        cs.MapRightKey("UserRefId");
        cs.ToTable("CompanyUsers");
    });

It worked as expected and generated the relevant script when I created my migration:

CreateTable(
    "dbo.CompanyUsers",
    c => new
        {
            CompanyRefId = c.Guid(nullable: false),
            UserRefId = c.Guid(nullable: false),
        })
    .PrimaryKey(t => new { t.CompanyRefId, t.UserRefId })
    .ForeignKey("dbo.Users", t => t.CompanyRefId, cascadeDelete: true)
    .ForeignKey("dbo.Companies", t => t.UserRefId, cascadeDelete: true)
    .Index(t => t.CompanyRefId)
    .Index(t => t.UserRefId);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM