我正在尝试从现有数据库生成实体框架代码第一个模型(不更改数据库模式)。此数据库过去曾用于生成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中使用此数据库而不更改其模式?
非常感谢, 菲尔
答案 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);
}
}