1

I'm trying to name the parent and child columns to something more meaningful instead of Element_ID and Element_ID1.

The Element table is generated without issue, but the second table is what I'd like to update the column names on.

I've tried adding the attribute [Column("ParentID")] above the parent property deceleration, but it has no affect on the generated table.

Entity Class

public class Element
{
    public Guid ID { get; set; } 
    public string Title { get; set; }
    public int Status { get; set; }       

    public virtual List<Element> Parent { get; set; }
    public virtual List<Element> Child { get; set; }
}

Generated Migration

CreateTable(
    "dbo.ElementElements",
    c => new
        {
            Element_ID = c.Guid(nullable: false),
            Element_ID1 = c.Guid(nullable: false),
        })
    .PrimaryKey(t => new { t.Element_ID, t.Element_ID1 })
    .ForeignKey("dbo.Elements", t => t.Element_ID)
    .ForeignKey("dbo.Elements", t => t.Element_ID1)
    .Index(t => t.Element_ID)
    .Index(t => t.Element_ID1);

I can make the second table output as I want if I use a second entity as such

public class Hierarchy
{
    public Guid ID { get; set; } 
    public virtual Guid ParentID { get; set; }
    public virtual Element Parent { get; set; }
    public virtual Guid ChildID { get; set; }
    public virtual Element Child { get; set; }
}

Which generated the following create script

CreateTable(
    "dbo.Hierarchies",
    c => new
        {
            ID = c.Guid(nullable: false),
            ParentID = c.Guid(nullable: false),
            ChildID = c.Guid(nullable: false),
        })
    .PrimaryKey(t => t.ID)
    .ForeignKey("dbo.Elements", t => t.ParentID)
    .ForeignKey("dbo.Elements", t => t.ChildID)
    .Index(t => t.ParentID)
    .Index(t => t.ChildID);

So is it possible to achieve the generating the second table using the column names I want with just one entity class?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Jerry
  • 1,775
  • 4
  • 22
  • 40

2 Answers2

2

If I understand your question correctly you just need an ordinary many-to-many mapping with Fluent API:

modelBuilder.Entity<Element>()
    .HasMany(e => e.Parent)
    .WithMany(e => e.Child)
    .Map(m => {
        m.ToTable("ElementMap"); // name of the link table
        m.MapLeftKey("ParentID");
        m.MapRightKey("ChildID");
    });

I would expect that the generated migration will respect this mapping and use the supplied table and column names.

Slauma
  • 175,098
  • 59
  • 401
  • 420
  • Sweet that does exactly what I wanted, thanks!. On a side note, is there a way to add additional properties to that ElementMap table? As in still have the parent/child public virutal lists in the Element entity, but also include a position property? – Jerry Mar 01 '13 at 16:57
  • 1
    @Jarek: No. If you want additional properties in the map/the join table you cannot use a many-to-many relationship anymore. Instead you must expose the join table as additional entity and then create two one-to-many relationships. Here is an example: http://stackoverflow.com/a/7053393/270591 – Slauma Mar 01 '13 at 17:57
  • Thanks, that was sort of what I was expecting. The problem as stated in my original question evolved to needing more information about the relationship, but your solution will definitely come in handy in the future. Thanks for that link, sheds some light on the next steps I'll have to do. – Jerry Mar 01 '13 at 19:59
0

For EF 6, I used the answer posted by Slauma on the current thread https://stackoverflow.com/a/15147308/13808871, but the column names on the relationship table were switched, to fix it, I exchanged the names of the parameters on the MapLeftKey and MapRightKey configuration methods.

modelBuilder.Entity<Element>()
                .HasMany(e => e.Parent)
                .WithMany(e => e.Child)
                .Map(m =>
                {
                    m.ToTable("ElementMap");
                    m.MapLeftKey("ChildID");
                    m.MapRightKey("ParentID");
                });

Hope this helps!

For more information go to the Microsoft documentation

capertuz
  • 11
  • 3
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/30822167) – Vapid Jan 18 '22 at 10:33