【问题标题】:Entity Framework 6: many to many relationship problem [closed]实体框架6:多对多关系问题[关闭]
【发布时间】: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“写一个总结具体问题的标题”。你会说你的标题是这样做的吗?
  • 也许使用占位符可能会有所帮助,请参阅:stackoverflow.com/questions/45409093/…
  • ....或根据此讨论更改您的数据模型,或使用 Load() 等,请参阅:stackoverflow.com/questions/1308158/…
  • mapper.Map 发生了什么,existing 及其集合之后的内容是什么?
  • 另外,你有一个 EDMX 并且类有数据注释?那不计算。您显示的类不是 EDMX 生成的类或您手动修改的类。

标签: c# entity-framework


【解决方案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
  • 它现在应该可以工作了。您只需在添加属性后重复数据库迁移
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-28
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多