EF Fluent API多对多具有不同的ID字段名称
在这个问题: Ef Many To Many ,一个关于如何手动指定链接表的答案。 但我有一个稍微独特的情况(我肯定不是真的很独特)。
我的两个表都有一个Id字段。 EG: [dbo].[Account].[Id]
和[dbo].[Person].[Id]
。 我的Code-First中的每个表都有以下OnModelCreating:
modelBuilder.Entity.HasKey(x => x.Id); modelBuilder.Entity.HasKey(x => x.Id);
但我的[dbo].[AccountsToPersons]...
表格有字段EG: [AccountId]
和[PersonId]
AccountsToPersons表不由代码中的类表示。
我显然已经有了一个现有的模型,但是我们使用EF Code-First Fluent API而不是从数据库更新模型。
那么如何更改此代码以使其与映射不同的ID列名称一起使用?
public DbSet Persons { get; set; } public DbSet Accounts { get; set; } . . . modelBuilder.Entity() .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();
,查询失败,出现以下错误:
- “无效的列名’Person_Id’。”
但是在运行Query时(from x in context.Persons select x).ToList();
,我没有错。
除了基本类型列之外,我的模型还添加了以下内容:
// In my Account Model, I also have this property: public IList Persons { get; set; } // In my Person Model, I also have this property: public IList Accounts { get; set; } // <-- in the Person model
请注意,即使我的Accounts查询通过并且包含字段信息, Persons
字段也始终为null,即使我确定AccountsToPersons
表中有链接。
尝试将p => p.Accounts
添加到WithMany
子句中:
modelBuilder.Entity() .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"); });
我刚为你的问题建立了一个测试解决方案,对我来说它看起来很有效。
我看到你做的一件事与我不同的是:
public IList Persons { get; set; } // <-- in the Account model public IList Accounts { get; set; } // <-- in the Person model
尝试修改为:
public DbSet Persons { get; set; } public DbSet Accounts { get; set; }
如果这不起作用,我将发布我的整个设置。
我的结构看起来像这样,它适用于您显示的查询:
public class Person { public int ID { get; set; } public string Name { get; set; } public IList Accounts { get; set; } } public class Account { public int ID { get; set; } public string Name { get; set; } public IList Persons { get; set; } } public class ApplicationDbContext : IdentityDbContext { public DbSet AccountSet { get; set; } public DbSet 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(); modelBuilder.Entity().HasKey(x => x.ID); modelBuilder.Entity().HasKey(x => x.ID); modelBuilder.Entity() .HasMany(a => a.Persons) .WithMany() .Map(w => { w.MapLeftKey("AccountId"); w.MapRightKey("PersonId"); w.ToTable("AccountsToPersons"); }); } }
您是否尝试过稍微修改AccountsToPersons映射:
modelBuilder.Entity() .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"); });