EF代码首先从数据库0..1到很多关系

时间:2015-07-09 09:13:06

标签: entity-framework code-first

我正在尝试从现有数据库生成实体框架代码第一个模型(不更改数据库模式)。此数据库过去曾用于生成edmx模型,我正在尝试使用Fluent Api或数据注释来实现等效模型。

我无法重现的关系是0..1到很多使用连接表(不是可以为空的外键)。

所以它看起来像这样:

TableA
{
   ID (PrimaryKey)
   TableB (0 or 1)
}

JoinTable
{
   TableA_FK (PrimaryKey, ForeignKey),
   TableB_FK (ForeignKey)
}

TableB
{
   ID (PrimaryKey)
   TableAs (Many)
}

这是否可以在代码第一种风格中实现,还是必须生成edmx模型才能在EF中使用此数据库而不更改其模式?

非常感谢, 菲尔

2 个答案:

答案 0 :(得分:0)

如果我理解正确,以下仅使用数据注释的代码应该创建您的模型。

public class TableA
{
    public int ID { get; set; }

    public JoinTable JoinTable { get; set; }
}

public class TableB
{
    public int ID { get; set; }

    public List<JoinTable> JoinTables{ get; set; }
}

public class JoinTable
{
    [Key, ForeignKey("TableA")]
    public int TableA_FK { get; set; }

    [ForeignKey("TableB")]
    public int TableB_FK { get; set; }

    public TableA TableA { get; set; }

    public TableB TableB { get; set; }
}     

有趣的是,如果您从此代码创建的数据库模型生成代码优先模型,则EF不会执行往返原始模型,然后EF简化模型并删除连接表并创建可为空的外键。

让我知道这是否有效。

答案 1 :(得分:0)

我可能错了,但我相信你在这里错过了一些概念......

如果除了外键之外没有任何列,为什么你有一个JoinTable?它没有意义...... IHMO在TableA中可以为空的外键是正确的。

使用Code-First时,意味着数据库中的所有内容都将由CODE表示。没有理由在您的数据库中有一个表但不在您的代码中......

EDMX处理这种关系,因为它使用“关联”https://msdn.microsoft.com/en-us/data/jj713299#Overview

...支持代码优先,您可以像这样代表您的数据库:

 public class JoinTable
 {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int TableA_FK { get; set; }

        public int TableB_FK { get; set; }

        //a future property here

        public virtual TableA TableA { get; set; }

        public virtual TableB TableB { get; set; }
 }

 public partial class TableA
 {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int TableAId { get; set; }

        [Required]
        [StringLength(50)]
        public string Name { get; set; }

        public virtual JoinTable JoinTable { get; set; }
}


public partial class TableB
{
        public TableB()
        {
            JoinTable = new HashSet<JoinTable>();
        }

        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int TableBId { get; set; }

        [Required]
        [StringLength(50)]
        public string Name { get; set; }

        public virtual ICollection<JoinTable> JoinTable { get; set; }
    }
}

public partial class Model1 : DbContext
{
    public Model1()
        : base("name=Model1")
    {
    }

    public virtual DbSet<JoinTable> JoinTable { get; set; }
    public virtual DbSet<TableA> TableA { get; set; }
    public virtual DbSet<TableB> TableB { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        modelBuilder.Entity<TableA>()
            .HasOptional(e => e.JoinTable)
            .WithRequired(e => e.TableA);

        modelBuilder.Entity<TableB>()
            .HasMany(e => e.JoinTable)
            .WithRequired(e => e.TableB)
            .HasForeignKey(e => e.TableB_FK)
            .WillCascadeOnDelete(false);
    }
}