I have three entities, BaseEntity
, Child
and GrandChild
, that are predictably linked together.
It goes like this:
public class BaseEntity
{
public string CompanyId { get; set; }
public string BaseEntityId { get; set; }
public virtual List<Child> Children { get; set; }
}
public class Child
{
public string CompanyId { get; set; }
public string BaseEntityId { get; set; }
public string ChildId { get; set; }
public virtual BaseEntity Parent { get; set; }
public virtual List<GrandChild> GrandChildren { get; set; }
}
public class GrandChild
{
public string CompanyId { get; set; }
public string BaseEntityId { get; set; }
public string ChildId { get; set; }
public string GrandChildId { get; set; }
public virtual Child ParentChild { get; set; }
}
public class BaseContext : DbContext
{
protected override void OnModelCreating(ModelBuilder p_mbuModel)
{
p_mbuModel.Entity<BaseEntity>().ToTable("T_BaseEntity");
p_mbuModel.Entity<BaseEntity>().HasKey(t => new { t.CompanyId, t.BaseEntityId });
p_mbuModel.Entity<Child>().ToTable("T_Child");
p_mbuModel.Entity<Child>().HasKey(t => new { t.CompanyId, t.BaseEntityId, t.ChildId });
p_mbuModel.Entity<Child>().HasOne(c => c.Parent).
WithMany(p => p.Children).
HasForeignKey(c => new { c.CompanyId, c.BaseEntityId }).
HasConstraintName("FK_Child_BaseEntity");
p_mbuModel.Entity<GrandChild>().ToTable("T_GrandChild");
p_mbuModel.Entity<GrandChild>().HasKey(t => new { t.CompanyId, t.BaseEntityId, t.ChildId, t.GrandChildId });
p_mbuModel.Entity<GrandChild>().HasOne(gc => gc.ParentChild).
WithMany(c => c.GrandChildren).
HasForeignKey(gc => new { gc.CompanyId, gc.BaseEntityId, gc.ChildId }).
HasConstraintName("FK_GrandChild_Child");
}
}
You'll note that it features no direct link from GrandChild
to BaseEntity
and no foreign key between GrandChild
and BaseEntity
. Which is consistent. I don't want that direct link. (If nothing else, it could lead to unpleasantness with cascading deletions.)
Still, when I launch Add-Migration, I get the following:
table.ForeignKey(
name: "FK_T_GrandChild_T_BaseEntity_BaseEntityId",
columns: x => { x.CompanyId, x.BaseEntityId },
principalTable: "T_BaseEntity",
principalColumns: new { "CompanyId", "BaseEntityId" },
onDelete: ReferentialAction.Cascade);
The very thing that I have tried to keep out. (On migrating, it creates the foreign key constraint that I don't want, and with that unwieldy name to boot.)
I have tried adding
p_mbuModel.Entity<GrandChild>().Ignore(t => new { t.CompanyId, t.BaseEntityId });
which raises an exception to the tune of
The expression 't => new <>f__AnonymousType10`2(CompanyId = t.CompanyId, BaseEntityId = t.BaseEntityId)' is not a valid property expression. The expression should represent a simple property access: 't => t.MyProperty'.
(I guess that's to be expected; that was a long shot on my behalf.)
I could add a GrandParent
property to GrandChild
and use Ignore()
on it, but that would require me to create the very link I want to hide.
I want no link between BaseEntity
and GrandChild
, neither as entities nor as database tables.
How can I achieve this?
... I'm embarrassed to admit this. When I posted the question, I trimmed the irrelevant parts of my classes. And I didn't notice that BaseEntity
included this line:
public virtual List<GrandChild> GrandChildren { get; set; }
I removed it and launched Add-Migration again. No link appeared between BaseEntity
and GrandChild
.
Apologies to any and all who tried to make sense of this incomplete riddle.