实体框架6代码优先,复合外键
本文关键字:复合 框架 代码 实体 | 更新日期: 2023-09-27 18:18:51
我将描述一个简化的版本:我有表TableA和TableB的id,和TableC的两个列,引用id在TableA和TableB。当我运行实体数据模型向导与代码首先从数据库和选择所有表,它生成的模型为TableA和TableB,但不是TableC。TableC包含在TableA的映射中。为什么?
如果我尝试手动创建TableC模型(或通过运行向导并仅选择TableC),然后将TableC的DbSet添加到我的DbContext,我得到运行时错误:
tableb: Name:已经定义了表'TableC'和schema 'dbo'的EntitySet ' tableb '。每个EntitySet必须引用一个唯一的模式和表。
有人能解释我如何访问TableC模型?我肯定我错过了什么,但我不知道到底是什么。
下面是在数据库test中创建这些表的简化SQL:CREATE TABLE [test].[dbo].TableA
(
[id] nvarchar(36) NOT NULL,
CONSTRAINT [PK_TableA] PRIMARY KEY CLUSTERED([id])
)
CREATE TABLE [test].[dbo].[TableB]
(
[id] nvarchar(36) NOT NULL,
CONSTRAINT [PK_TableB] PRIMARY KEY CLUSTERED([id])
)
CREATE TABLE [test].[dbo].[TableC]
(
[aId] nvarchar(36) NOT NULL,
[bId] nvarchar(36) NOT NULL,
CONSTRAINT [PK_TableC] PRIMARY KEY CLUSTERED([aId],[bId])
)
ALTER TABLE [test].[dbo].[TableC]
ADD CONSTRAINT [FK_TableC_TableA]
FOREIGN KEY([aId]) REFERENCES [dbo].[TableA]([id])
ALTER TABLE [test].[dbo].[TableC]
ADD CONSTRAINT [FK_TableC_TableB]
FOREIGN KEY([bId]) REFERENCES [dbo].[TableB]([id])
这是向导生成的DbContext
:
public virtual DbSet<TableA> TableA { get; set; }
public virtual DbSet<TableB> TableB { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<TableA>()
.HasMany(e => e.TableB)
.WithMany(e => e.TableA)
.Map(m => m.ToTable("TableC").MapLeftKey("aId").MapRightKey("bId"));
}
这是TableA的模型(类似于TableB):
[Table("TableA")]
public partial class TableA
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public TableA()
{
TableB = new HashSet<TableB>();
}
[StringLength(36)]
public string id { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<TableB> TableB { get; set; }
}
最后,如果我为TableC生成一个模型:
[Table("TableC")]
public partial class TableC
{
[Key]
[Column(Order = 0)]
[StringLength(36)]
public string aId { get; set; }
[Key]
[Column(Order = 1)]
[StringLength(36)]
public string bId { get; set; }
}
我认为这是实体框架的默认行为。代码中根本不需要TableC。or映射器试图向我们的开发人员隐藏数据库的复杂性,而实体框架可以帮助你,因为它隐藏了这种n对m的关系,并为你构建了一个带有两个集合的。net方法。TableC作为实体有什么好处?