In this question: Ef Many To Many, an answer came up on how to manually specify a linking table. But I have a slightly unique situation (which I'm sure isn't really unique).
My two tables each have an Id field. E.G.: [dbo].[Account].[Id]
and [dbo].[Person].[Id]
. Each of these tables in my Code-First has the following OnModelCreating:
modelBuilder.Entity<Account>.HasKey(x => x.Id);
modelBuilder.Entity<Person>.HasKey(x => x.Id);
But my [dbo].[AccountsToPersons]...
table has fields E.G.: [AccountId]
and [PersonId]
The AccountsToPersons table is not represented by a class in code.
I obviously already have an existing Model, but we are using EF Code-First Fluent API instead of updating model from database.
So how do I change this code to make it work with mapping different ID columns names?
public DbSet<Person> Persons { get; set; }
public DbSet<Account> Accounts { get; set; }
. . .
modelBuilder.Entity<Account>()
.HasMany(a => a.Persons)
.WithMany()
.Map(x =>
{
x.MapLeftKey("AccountId"); // <-- Account.Id to AccountsToPersons.AccountId??
x.MapRightKey("PersonId"); // <-- Person.Id to AccountsToPersons.PersonId??
x.ToTable("AccountsToPersons");
});
When running a basic Linq To EF Query (from x in context.Accounts select x).ToList();
, the query fails with the following error:
But when running the Query (from x in context.Persons select x).ToList();
, I get no error.
Other than basic typed columns, my models have these added to them:
// In my Account Model, I also have this property:
public IList<Person> Persons { get; set; }
// In my Person Model, I also have this property:
public IList<Account> Accounts { get; set; } // <-- in the Person model
And please note that even though my Accounts query passes and has field information, the Persons
field is always null, even though I'm sure there are links in my AccountsToPersons
table.
Try adding p => p.Accounts
to your WithMany
clause:
modelBuilder.Entity<Account>()
.HasMany(a => a.Persons)
.WithMany(p => p.Accounts) // <-- I think this should fix it
.Map(x =>
{
x.MapLeftKey("AccountId"); // <-- Account.Id to AccountsToPersons.AccountId??
x.MapRightKey("PersonId"); // <-- Person.Id to AccountsToPersons.PersonId??
x.ToTable("AccountsToPersons");
});
I just built up a test solution for your problem and for me it looks that is working.
One thing that i see you did different than me is:
public IList<Person> Persons { get; set; } // <-- in the Account model
public IList<Account> Accounts { get; set; } // <-- in the Person model
Try modifying into this:
public DbSet<Person> Persons { get; set; }
public DbSet<Account> Accounts { get; set; }
If this doesn't work i`ll post my entire setup.
My structure looks like this and it works for the queries you displayed:
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public IList<Account> Accounts { get; set; }
}
public class Account
{
public int ID { get; set; }
public string Name { get; set; }
public IList<Person> Persons { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<Account> AccountSet { get; set; }
public DbSet<Person> PersonSet { get; set; }
public ApplicationDbContext()
: base("DefaultConnection")
{
this.Database.Log = (msg) => { Debug.Write(msg); };
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Account>().HasKey(x => x.ID);
modelBuilder.Entity<Person>().HasKey(x => x.ID);
modelBuilder.Entity<Account>()
.HasMany(a => a.Persons)
.WithMany()
.Map(w =>
{
w.MapLeftKey("AccountId");
w.MapRightKey("PersonId");
w.ToTable("AccountsToPersons");
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With