实体框架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; }
}

实体框架6代码优先,复合外键

我认为这是实体框架的默认行为。代码中根本不需要TableC。or映射器试图向我们的开发人员隐藏数据库的复杂性,而实体框架可以帮助你,因为它隐藏了这种n对m的关系,并为你构建了一个带有两个集合的。net方法。TableC作为实体有什么好处?