EF core many to many configuration not working with Fluent API

asp.net c# entity-framework entity-framework-core

Question

I am having trouble with understanding and implementing a many to many repationship using the FLuent API and EF Core.

I have looked at this question and set up my relationship exactly as that but I am getting the following error:

Error CS1061 'CollectionNavigationBuilder' does not contain a definition for 'WithMany' and no extension method 'WithMany' accepting a first argument of type 'CollectionNavigationBuilder' could be found (are you missing a using directive or an assembly reference?)

This is my intention. I have a client who has many jobs. I should be able to get all the jobs linked to that client. EF should create the join table in the background...

Here are my classes:

public class Client : IEntityBase
{
    public int Id { get; set; }

    public int? JobId { get; set; }
    public ICollection<Job> Jobs { get; set; }
}

public class Job : IEntityBase
{
    public int Id { get; set; }
}

//my interface
public interface IEntityBase
{
    int Id { get; set; }
}

EDIT Here is the Fluent API I tried and where I get the error on the ".withMany"

        modelBuilder.Entity<Client>()
            .HasMany(p => p.Jobs)
            .WithMany(p => p.clients)
            .Map(m =>
            {
                m.MapLeftKey("ClientId");
                m.MapRightKey("JobId");
                m.ToTable("ClientJob");
            });

I am using a generic repository pattern as per Chris Sakell's blog. Here is the code for retrieving clients:

        IEnumerable<Client> _clients = _clientRepository
           .AllIncluding(s => s.Creator, s => s.Jobs, s => s.State)
           .OrderBy(s => s.Id)
           .Skip((currentPage - 1) * currentPageSize)
           .Take(currentPageSize)
           .ToList();

and I am using the generic code as per:

    public virtual IEnumerable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties)
    {
        IQueryable<T> query = _context.Set<T>();
        foreach (var includeProperty in includeProperties)
        {
            query = query.Include(includeProperty);
        }
        return query.AsEnumerable();
    }

How do I configure this so I can retrieve the jobs as well using the includeproperty as per the Allincluding statement above?

1
8
5/23/2017 12:17:06 PM

Popular Answer

The Fluent API example you are trying to implement comes from EF 6. Many-to-Many relationship configuration is a little different in EF Core. For a start, you need to include an entity to represent the join/bridging table:

public class ClientsJobs
{
    public int ClientId { get; set; }
    public int JobId { get; set; }
    public Client Client { get; set; }
    public Job Job { get; set; }
}

Then you configure it like this in the OnModelCreating method:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<ClientsJobs>()
        .HasKey(x => new { x.ClientId, x.JobId });

    modelBuilder.Entity<ClientsJobs>()
        .HasOne(x => x.Client)
        .WithMany(y => y.Jobs)
        .HasForeignKey(y => y.JobId);

    modelBuilder.Entity<ClientsJobs>()
        .HasOne(x => x.Job)
        .WithMany(y => y.Clients)
        .HasForeignKey(y => y.ClientId);
}

See more about it here: http://www.learnentityframeworkcore.com/configuration/many-to-many-relationship-configuration

Note: you do need to include navigational properties for both ends of the relationship in the related classes, so you need to add a Clients property to your Job entity.

13
2/21/2017 8:20:49 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow