EF核心多对多配置无法使用Fluent API

时间:2017-02-20 06:34:08

标签: c# asp.net entity-framework entity-framework-core

我无法使用FLuent API和EF Core理解和实现多对多的重复。

我查看了this问题并完全建立了我的关系,但我收到以下错误:

  

错误CS1061' CollectionNavigationBuilder'不包含' WithMany'的定义并且没有任何扩展方法' WithMany'接受类型' CollectionNavigationBuilder'的第一个参数。可以找到(你错过了使用指令或程序集引用吗?)

这是我的意图。我有一个有很多工作的客户。我应该能够获得与该客户相关联的所有工作。 EF应该在后台创建连接表...

以下是我的课程:

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; }
}

编辑以下是我尝试过的Fluent API以及我在&#34; .withMany&#34;

上收到错误的地方
        modelBuilder.Entity<Client>()
            .HasMany(p => p.Jobs)
            .WithMany(p => p.clients)
            .Map(m =>
            {
                m.MapLeftKey("ClientId");
                m.MapRightKey("JobId");
                m.ToTable("ClientJob");
            });

我正在使用Chris Sakell博客的通用存储库模式。以下是检索客户端的代码:

        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();

我正在使用通用代码:

    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();
    }

如何配置,以便我可以根据上面的Allincluding语句使用includeproperty检索作业?

3 个答案:

答案 0 :(得分:6)

您尝试实现的Fluent API示例来自EF 6.多对多关系配置在EF Core中略有不同。首先,您需要包含一个实体来表示join / bridging表:

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

然后在OnModelCreating方法中配置它:

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);
}

点击此处了解详情:http://www.learnentityframeworkcore.com/configuration/many-to-many-relationship-configuration

注意:您执行需要在相关类中包含关系两端的导航属性,因此您需要向Clients实体添加Job属性

答案 1 :(得分:4)

对于 EF Core 5.0 及更高版本,您可以(最终)对多对多使用直接关系:

modelBuilder
.Entity<Post>()
.HasMany(p => p.Tags)
.WithMany(p => p.Posts)
.UsingEntity(j => j.ToTable("PostTags"));

来源:Relationships - EF Core | Microsoft (many-to-many)

答案 2 :(得分:0)

您也应该将Clients属性添加到Job类:

public class Job : IEntityBase
{
   public int Id { get; set; }
   public ICollection<Client> Clients{ get; set; }
}

然后一切都应该整齐。