多对多 - “无法确定一对一关系的子/依赖方”

Posted

技术标签:

【中文标题】多对多 - “无法确定一对一关系的子/依赖方”【英文标题】:Many to Many - "child/dependent side could not be determined for the one-to-one relationship" 【发布时间】:2022-01-02 17:31:45 【问题描述】:

我正在尝试实现多对多关系,但我得到:

无法确定一对一的孩子/依赖方 'Artikel.Lager' 和 'Lager.Artikel' 之间的关系。识别 关系的子/依赖方,配置外部 关键财产。如果这些导航不应该是相同的一部分 关系配置它们而不指定反向。看 http://go.microsoft.com/fwlink/?LinkId=724062 了解更多详情。

ER:

代码:

  #region Data

    [Table("Lager")]
    public class Lager
    
        public Guid Id  get; set;  = Guid.NewGuid();
        public string Name  get; set;  = "";
        public string Strasse  get; set;  = "";
        public string PLZ  get; set;  = "";
        public string Ort  get; set;  = "";

        public Artikel Artikel  get; set; 
    

    [Table("LagerArtikel")]
    public class LagerArtikel
    
        public Guid Id  get; set;  = Guid.NewGuid();

        //[ForeignKey("Lager")]
        //public Guid LagerId  get; set; 

        //[ForeignKey("Artikel")]
        //public Guid ArtikelId  get; set; 

        public int Menge  get; set; 

        public ICollection<Artikel> Artikels  get; set; 
        public ICollection<Lager> Lagers  get; set; 
    

    [Table("Artikel")]
    public class Artikel
    
        public Guid Id  get; set;  = Guid.NewGuid();
        public string Name  get; set;  = "";
        public decimal EinkaufspreisNettoEuro  get; set; 
        public Lager Lager  get; set; 
    

    #endregion

    #region Context

    // => EF Core
    /*
    Add-Migration Initial -context _1_Testing.XDBContextTesting -o Migrations\XDBContextTestingMig
    add-migration -Name A3 -Project compDatMVP -context _1_Testing.XDBContextTesting
    Update-Database -context _1_Testing.XDBContextTesting 
    */

    public class XDBContextTesting : DbContext
    
        public DbSet<Lager> Lager  get; set; 
        public DbSet<LagerArtikel> LagerArtikel  get; set; 
        public DbSet<Artikel> Artikel  get; set; 

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        
            optionsBuilder.UseSqlServer(new string(Konstanten.ConnectionString.Replace("#db#", "compDat__1__Testing")));
        

        public XDBContextTesting() : base()
        
        

        public XDBContextTesting(DbContextOptions<XDBContextTesting> options) : base(options)
        
        
    

    #endregion

我到底错过了什么?

【问题讨论】:

【参考方案1】:

你错过了整个多对多:)

一个贮藏啤酒将有许多 Artikel,而一个Artikel 将有许多贮藏啤酒。

public class Lager

   [Key]
   public int LagerId  get; set; 
   // ...
   public virtual ICollection<LagerArtikel> LagerArtikels  get; set;  = new List<LagerArtikel>();


public class Artikel

   [Key]
   public int ArtikelId  get; set; 
    // ...
   public virtual ICollection<LagerArtikel> LagerArtikels  get; set;  = new List<LagerArtikel>();


public class LagerArtikel

    [Key]
    public int LagerArtikelId get; set;
    [ForeignKey("Lager")]
    public int LagerId get; set;
    [ForeignKey("Artikel")]
    public int ArtikelId get; set;

    // or just use a composite PK:
    //[Key, Column(Order=1), ForeignKey("Lager")]
    //public int LagerId get; set;
    //[Key, Column(Order=2), ForeignKey("Artikel")]
    //public int ArtikelId get; set;

    public virtual Lager Lager  get; set; 
    public virtual Artikel Artikel  get; set; 
    public int Menge  get; set; 

由于链接实体 (LagerArtikel) 将具有其他属性,例如 Menge,您需要使用对该实体的引用。如果您只想要一个仅包含 LagerId 和 ArtikelId 的 LagerArtikel 表作为复合 PK 来表示多对多链接,使用 EF6 和 EF Core 5+ 您可以取消 LagerArtikel 实体,并且 Lager 可以拥有 Artikel 的集合而 Artikel 有一个 Lagers 集合,EF 可以在其中管理关系和对应表,而无需额外的实体。

从表格的角度来考虑。你会在 LagerArtikel 桌子上放什么?它将有一个 LagerId 和一个 ArtikelId,它不能在一行中存储 many 个贮藏啤酒和 许多 个 Artikel,而是该表中的每一行都将一个 Artikel 链接到一个贮藏啤酒。许多行将共享一个 ArtikelId,许多行将共享一个 LagerId。

【讨论】:

【参考方案2】:

您需要替换 Lager 类中的 public Artikel Artikel get; set; 并替换 Artikel 类中的 public Lager Lager get; set;

您宁愿在两个类中都添加public LagerArtikel LagerArtikel get; set;

【讨论】:

以上是关于多对多 - “无法确定一对一关系的子/依赖方”的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis一对多,多对一,多对多

关联查询 一对多,多对一,多对多,自关联

mybatis 一对一 一对多 多对多

数据库表设计(一对多,多对多)

数据库表设计(一对多,多对多)

数据库 一对多,多对多 表设计