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

时间:2015-10-23 04:26:35

标签: c# sql-server entity-framework

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

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

  

TableATableB:名称:EntitySet' TableATableB'使用架构&#d;'和表' TableC'已经定义了。每个EntitySet都必须引用一个唯一的模式和表。

有人能解释我如何访问TableC模型吗?我确定我错过了一些东西,但我无法弄明白到底是什么......

这是在数据库中创建这些表的简化SQL' test':

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

1 个答案:

答案 0 :(得分:0)

我认为这是Entity Framework的默认行为。 您只需在代码中不需要TableC。 OR-Mappers试图隐藏来自我们开发人员的数据库的复杂性,实体框架可以帮助您,因为它隐藏了这种与m的关系,并为您构建了一个类似.Net的方法。 您将TableC作为实体有什么好处?