繁体   English   中英

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

[英]Entity Framework 6 Code First, Composite Foreign Key

我将描述一个简化的版本:我的表TableA和TableB带有ID,而TableC的两列则引用了TableA和TableB中的ID。 当我从数据库中使用Code First运行实体数据模型向导并选择所有表时,它将为TableA和TableB生成模型,但不会为TableC生成模型。 TableC包含在TableA的映射中。 为什么?

如果尝试手动为TableC创建模型(或通过运行向导并仅选择TableC),然后将TableC的DbSet添加到我的DbContext中,则会收到运行时错误:

TableATableB:名称:具有模式'dbo'和表'TableC'的EntitySet'TableATableB'已经定义。 每个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-Mappers试图向我们的开发人员隐藏数据库的复杂性,而Entity Framework可以为您提供帮助,因为它隐藏了这种n对m的关系并为您构造了一个具有两个集合的.Net式方法。 您将TableC作为实体有什么好处?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM