实体框架6:多对多关系问题[关闭]

Posted

技术标签:

【中文标题】实体框架6:多对多关系问题[关闭]【英文标题】:Entity Framework 6: many to many relationship problem [closed] 【发布时间】:2021-08-04 08:40:11 【问题描述】:

我正在努力处理子表的多对多关系。 EF6

表1:

Id int
Name string

表2:

Id int
ParentId int fk
ChildId int fk

Table2 中有两个指向 Table1 的链接 - ChildId 和 ParentId,它们是 Table1 中的 Id 的外键。 Entity Framework在调用时会正确更新ParentId,但是将ChildId更新为Table1 Id的ParentId?

public partial class GeographicPolygon : IPublishingEntity
       
    public GeographicPolygon()
                
        this.GeographicPolygonLinkParents = new HashSet<GeographicPolygonLink>();
        this.GeographicPolygonLinkChildren = new HashSet<GeographicPolygonLink>();
    

    public int Id  get; set; 
    public System.Guid InternalId  get; set;         
    public string Name  get; set;         
        
    [InverseProperty("GeographicPolygonParent")] 
    public virtual ICollection<GeographicPolygonLink> GeographicPolygonLinkParents  get; set; 
    
    [InverseProperty("GeographicPolygonChild")] 
    public virtual ICollection<GeographicPolygonLink> GeographicPolygonLinkChildren  get; set; 


public partial class GeographicPolygonLink : IEntity
        
    public int Id  get; set;                 
    public int ParentId  get; set; 
    public int ChildId  get; set;         

    [ForeignKey("ChildId")] 
    public virtual GeographicPolygon GeographicPolygonChild  get; set; 

    [ForeignKey("ParentId")] 
    public virtual GeographicPolygon GeographicPolygonParent  get; set; 

传入的数据。


  "Id": 3,
  "Name": "New GeoPoly 2",    
  "GeographicPolygonLinkChildren": [
    
      "ParentId": 3,
      "ChildId": 10,
    ,
    
      "ParentId": 3,
      "ChildId": 11,
    
  ]

更新的调用是:

var internalId = Guid.Parse(document.InternalId);
var existing = await context.Set<TTarget>().FirstOrDefaultAsync(x => x.InternalId == internalId);
if (existing == null)

    existing = new TTarget CreatedDate = DateTime.Now;
    context.Set<TTarget>().Add(existing);


mapper.Map(document, existing);

await context.SaveChangesAsync();

我在更新之前查看“现有”,并且 Id 都是正确的。 ChildId 的 10 和 11。

在 SaveChangeAsync 之后数据库有:

ID   ParentId  ChildId
320  3         3
321  3         3

即使有注释,我也无法正确更新 ChildId。

在我的模型构建器中,我有:

builder.EntitySet<GeographicPolygonModel>("GeographicPolygon");
builder.EntitySet<GeographicPolygonLinkModel>("GeographicPolygonLink");

我的 edmx 有:

<EntityType Name="GeographicPolygon">
  <Key>
    <PropertyRef Name="Id" />
  </Key>
  <Property Name="Id" Type="Int32" Nullable="false" />          
  <Property Name="Name" Type="String" Nullable="false" />                    
  <NavigationProperty Name="GeographicPolygonLinkParents" Relationship="DataContext.fkGeographicPolygonLinkParentId_GeographicPolygon" FromRole="GeographicPolygon" ToRole="GeographicPolygonLink" />
  <NavigationProperty Name="GeographicPolygonLinkChildren" Relationship="DataContext.fkGeographicPolygonLinkChildId_GeographicPolygon" FromRole="GeographicPolygon" ToRole="GeographicPolygonLink" />
</EntityType>

我看了又看,但我尝试过的都没有奏效?

有什么想法吗?

【问题讨论】:

来自How to Ask:“写一个总结具体问题的标题”。你会说你的标题是这样做的吗? 也许使用占位符可能会有所帮助,请参阅:***.com/questions/45409093/… ....或根据此讨论更改您的数据模型,或使用 Load() 等,请参阅:***.com/questions/1308158/… mapper.Map 发生了什么,existing 及其集合之后的内容是什么? 另外,你有一个 EDMX 并且类有数据注释?那不计算。您显示的类不是 EDMX 生成的类或您手动修改的类。 【参考方案1】:

尝试添加导航属性

public partial class GeographicPolygonLink : IEntity
        
    public int Id  get; set;                 
    public int ParentId  get; set; 
    public int ChildId  get; set;         

    
    [ForeignKey(nameof(ChildId))]
   [InverseProperty(nameof(GeographicPolygon.GeographicPolygonLinkChildren))]
    public virtual GeographicPolygon GeographicPolygonChild  get; set; 

    [ForeignKey(nameof(ParentId))]
    [InverseProperty(nameof(GeographicPolygon.GeographicPolygonLinkParents))]
    public virtual GeographicPolygon GeographicPolygonParent  get; set; 



public partial class GeographicPolygon : IPublishingEntity
       
   ...... 
        
   
  [InverseProperty(nameof(GeographicPolygonLink.GeographicPolygonParent))]
    public virtual ICollection<GeographicPolygonLink> GeographicPolygonLinkParents  get; set; 
    
    [InverseProperty(nameof(GeographicPolygonLink.GeographicPolygonChild))] 
    public virtual ICollection<GeographicPolygonLink> GeographicPolygonLinkChildren  get; set; 

【讨论】:

试过了。没有运气:( @AndMac 是什么错误? 没有错误,就是这样。它只是不使用正确的数据更新列。无论我将 ChildId 设置为什么。如果我查看 SQL 探查器,我可以看到 Insert 语句都有 3 作为 childId exec sp_executesql N'INSERT [dbo].[GeographicPolygonLink]([ParentId], [ChildId]) VALUES (@0, @1) SELECT [Id], [RecordVersion] 来自 [dbo].[GeographicPolygonLink] 其中@@ROWCOUNT > 0 AND [Id] = scope_identity()',N'@0 int,@1 int,@0=3,@1=3 它现在应该可以工作了。您只需在添加属性后重复数据库迁移

以上是关于实体框架6:多对多关系问题[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

多对多关系实体框架核心db优先

实体框架多对多关系错误

实体框架在多对多关系中重复条目

使用实体框架从多对多关系中选择数据

实体框架中的多对多关系导致无限循环

Remove() 不适用于实体框架中的多对多关系