在ef核心中以多对多关系直接访问相关数据(并跳过链接类)

让我们说我想拥有一个A且很多B的班级A; 我可以通过创建类AB,向ICollection<AB> ABsA类添加B字段,然后通过B访问ABs来实现这一点。类A的属性。这可行。 但是我想知道是否有一种方法可以直接从类B访问相关的A数据,而不是通过ABs属性来访问数据。

我可以想象有几种方法可以做到(我都没有设法上班):

  • public ICollection<B> Bs => this.ABs.Select(item => item.B).ToList();,但是没有,我没有空异常,即使我在此ABs中确实包含了Bscontext.As.Include(item => item.ABs).ThenInclude(item => item.B);

  • ef core的流畅api(不知道怎么做)

using microsoft.EntityFrameworkCore;
using System;
using Context;

namespace ConsoleApp1 {
  class Program
  {
    static void Main(string[] args)
    {
      using var context = new ZContext();
      context.Database.EnsureDeleted();
      context.Database.EnsureCreated();
      var A = context.As.Include(item => item.ABs).ThenInclude(item => item.B);
      foreach (var a in A) {
        Console.WriteLine(a.Bs);
      }

      return;
    }
  }
}

using microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Context
{
  public class IDed
  {
    #region Constructors
    public IDed()
    {
      ID = Guid.NewGuid();
    } 
    #endregion

    public Guid ID { get; set; }
  }
  public class A : IDed
  {
    public ICollection<AB> ABs { get; set; }
    public ICollection<B> Bs { 
      get {
        return ABs.Select(item => item.B).ToList();
      }
    }
  }
  public class B : IDed
  {
    public ICollection<AB> ABs { get; set; }
  }
  public class AB
  {
    #region Constructors
    public AB()
    {

    }
    public AB(A a,B b)
    {
      this.AID = a.ID;
      this.BID = b.ID;
    } 
    #endregion

    public A A { get; set; } public Guid AID { get; set; }
    public B B { get; set; } public Guid BID { get; set; }
  }
  public class ZContext : DbContext
  {
    public DbSet<A> As { get; set; }
    public DbSet<B> Bs { get; set; }

    protected override void Onconfiguring(DbContextOptionsBuilder optionsBuilder)
    {
      optionsBuilder.UseSqlite("Data Source=111.db3");
    }

    protected override void OnmodelCreating(ModelBuilder mb)
    {
      #region Keys
      mb.Entity<AB>().HasKey(item => new { item.AID,item.BID });
      #endregion
      #region Relations
      // ???
      #endregion
      var a1 = new A();
      var a2 = new A();
      mb.Entity<A>().HasData(a1,a2);

      var b1 = new B(); 
      var b2 = new B();
      mb.Entity<B>().HasData(b1,b2);
      mb.Entity<AB>().HasData(
        new AB(a1,b1),new AB(a1,b2),new AB(a2,b2)
      );
    }
  }
}

使用第一种方法,即使我System.ArgumentNullException: 'Value cannot be null. (Parameter 'source')'Include的字段都相同,也会出现ThenInclude错误。

我意识到AB类必须以任何方式保留,但是可以实现此配置,以及这样做的正确方法。

dongjian_011 回答:在ef核心中以多对多关系直接访问相关数据(并跳过链接类)

该异常是由EF推断默认映射约定引起的。也就是说,在构建实体模型时,EF遇到属性A.Bs并尝试为其找到数据库映射。正是在很早的时候发生异常。知道这一点后,修复很容易:只需取消映射属性即可:

[NotMapped]
public ICollection<B> Bs
{
    get
    {
        return ABs.Select(item => item.B).ToList();
    }
}

protected override void OnModelCreating(ModelBuilder mb)
{
    ...
    mb.Entity<A>().Ignore(a => a.Bs);

当然,即使没有例外,也应取消映射该属性,因为您不希望该属性反映在数据库关联中。

本文链接:https://www.f2er.com/3158628.html

大家都在问