EF Fluent API多对多具有不同的ID字段名称

时间:2014-11-21 18:21:14

标签: c# entity-framework ef-fluent-api

在这个问题:Ef Many To Many中,提出了如何手动指定链接表的答案。但我有一个稍微独特的情况(我确定它并不是非常独特)。

我的两个表都有一个Id字段。 E.G。:[dbo].[Account].[Id][dbo].[Person].[Id]。我的Code-First中的每个表都有以下OnModelCreating:

modelBuilder.Entity<Account>.HasKey(x => x.Id);
modelBuilder.Entity<Person>.HasKey(x => x.Id);

但我的[dbo].[AccountsToPersons]...表格包含字段E.G。:[AccountId][PersonId]

AccountsToPersons表未由代码中的类表示。

我显然已经有了一个现有的Model,但我们使用的是EF Code-First Fluent API,而不是从数据库中更新模型。

那么如何更改此代码以使其能够映射不同的ID列名称?

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");
  });

运行基本的Linq To EF查询(from x in context.Accounts select x).ToList();时,查询失败并显示以下错误:

  • &#34;列名无效&#39; Person_Id&#39;。&#34;

但是在运行查询(from x in context.Persons select x).ToList();时,我没有收到任何错误。

除了基本类型列之外,我的模型还添加了这些列:

// 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

请注意,即使我的帐户查询已通过且包含字段信息,Persons字段也始终为空,即使我确定AccountsToPersons表中有链接。< / p>

3 个答案:

答案 0 :(得分:4)

尝试将p => p.Accounts添加到您的WithMany子句:

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");
  });

答案 1 :(得分:2)

我刚为你的问题建立了一个测试解决方案,对我来说它看起来很有效。

我认为你做的一件事与我不同的是:

public IList<Person> Persons { get; set; } // <-- in the Account model
public IList<Account> Accounts { get; set; } // <-- in the Person model

尝试修改为:

public DbSet<Person> Persons { get; set; }
public DbSet<Account> Accounts { get; set; }

如果这不起作用,我将发布我的整个设置。

我的结构看起来像这样,它适用于您显示的查询:

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");
            });
    }
}

答案 2 :(得分:0)

您是否尝试过轻微修改AccountsToPersons映射:

 modelBuilder.Entity<Account>()
   .HasMany(a => a.Persons)
   .WithMany(p => p.Accounts) <-- Change
   .Map(x =>
    {
         x.MapLeftKey("AccountId"); // <-- Account.Id to AccountsToPersons.AccountId??
         x.MapRightKey("PersonId"); // <-- Person.Id  to AccountsToPersons.PersonId??
         x.ToTable("AccountsToPersons");
    });