Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework EF代码首先从数据库0..1到多个关系_Entity Framework_Code First - Fatal编程技术网

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

Entity framework EF代码首先从数据库0..1到多个关系,entity-framework,code-first,Entity Framework,Code First,我试图从现有数据库生成实体框架代码优先模型(不更改数据库模式)。该数据库过去曾用于生成edmx模型,我正在尝试使用Fluent Api或数据注释实现等效模型 我无法使用联接表(不是可为空的外键)重现的关系是0..1对多 所以它看起来像这样: TableA { ID (PrimaryKey) TableB (0 or 1) } JoinTable { TableA_FK (PrimaryKey, ForeignKey), TableB_FK (ForeignKey) }

我试图从现有数据库生成实体框架代码优先模型(不更改数据库模式)。该数据库过去曾用于生成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)
}
 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);
    }
}
这在代码优先的样式中是可以实现的,还是我必须生成一个edmx模型才能在EF中使用该数据库而不更改其模式

非常感谢,,
Phil

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

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; }
}     
公共类表a
{
公共int ID{get;set;}
公共连接表连接表{get;set;}
}
公共类表格B
{
公共int ID{get;set;}
公共列表连接表{get;set;}
}
公共类可联接
{
[键,外键(“表A”)]
公共int表a_FK{get;set;}
[外键(“表B”)]
公共int TableB_FK{get;set;}
公共表格表格{get;set;}
公共TableB TableB{get;set;}
}     
有趣的是,如果您从代码创建的数据库模型生成代码优先的模型,那么EF不会执行返回原始模型的往返过程,EF会简化模型并删除联接表并创建一个可为空的外键


让我知道这是否有效。

下面是一个不使用JoinTable类的示例。联接表是通过fluent api配置的

class DataContext : DbContext
    {
        public DataContext(string connectionString)
            : base(connectionString)
        { }

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

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<TableA>().ToTable("TableA");
            modelBuilder.Entity<TableB>().ToTable("TableB");

            modelBuilder.Entity<TableB>()
                .HasMany(x => x.TableAs)
                .WithMany()
                .Map(m =>
                {
                    m.ToTable("JoinTable");
                    m.MapLeftKey("TableA_FK");
                    m.MapRightKey("TableB_FK");
                });
        }
    }

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

    class TableB
    {
        public int ID { get; set; }
        public ICollection<TableA> TableAs { get; set; }
    }

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

如果JoinTable除了外键之外没有任何列,为什么还要有它呢?这没有道理。。。IHMO表a中的可空外键是正确的方法

当您首先使用代码时,这意味着数据库中的所有内容都将由代码表示。没有理由在数据库中有一个表,但在代码中没有

EDMX处理该关系,因为它使用“关联”

…首先回到代码,您可以这样表示您的数据库:

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

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

TableB
{
   ID (PrimaryKey)
   TableAs (Many)
}
 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);
    }
}
公共类JoinTable
{
[关键]
[数据库生成(DatabaseGeneratedOption.None)]
公共int表a_FK{get;set;}
公共int TableB_FK{get;set;}
//这里的未来财产
公共虚拟表格表格{get;set;}
公共虚拟表b TableB{get;set;}
}
公共部分类表a
{
[关键]
[数据库生成(DatabaseGeneratedOption.Identity)]
public int TableAId{get;set;}
[必需]
[长度(50)]
公共字符串名称{get;set;}
公共虚拟连接表连接表{get;set;}
}
公共部分类表B
{
公开表格b(
{
JoinTable=newhashset();
}
[关键]
[数据库生成(DatabaseGeneratedOption.Identity)]
公共int TableBId{get;set;}
[必需]
[长度(50)]
公共字符串名称{get;set;}
公共虚拟ICollection连接表{get;set;}
}
}
公共部分类Model1:DbContext
{
公共模型1()
:base(“name=Model1”)
{
}
公共虚拟数据库集连接表{get;set;}
公共虚拟数据库集表a{get;set;}
公共虚拟数据库集TableB{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity()
.has可选(e=>e.JoinTable)
.需要(e=>e.TableA);
modelBuilder.Entity()
.HasMany(e=>e.JoinTable)
.WithRequired(e=>e.TableB)
.HasForeignKey(e=>e.TableB_FK)
.WillCascadeOnDelete(假);
}
}

这似乎接近我想要的。如果TableA可以直接引用它的TableB而不必通过联接表,那么这将是一个完整的答案。这发生在数据库第一个edmx模型方法中-连接表隐藏在模型中。@PhilWithington是的,我知道你的意思。我不知道如何才能做到这一点。您可能有另一个
NotMapped
属性取消引用
JoinTable
属性。建议不错。不过,缺乏往返可能会在未来产生问题。谢谢你的想法。你几乎都可以用它来做,但我认为这需要在联接表中为表中的每一行指定一行。数据库模型是什么样子的?如果
JoinTable
有一个PK/FK引用表a,那么关联只能是*(a)到0..1(B)。我把它弄混了吗?基本上,A可能有一个B(尽管许多人没有),B可能有许多A,尽管大多数人没有。您将得到两个独立的关系:TableA和TableB之间的1:1关系,以及使用联接表的同一个表之间的多:多关系是的,但是如果需要匹配模式,可以避免吗?据我所知,这与问题中描述的模式相匹配。这是我见过的最接近我想要实现的答案。查看代码时让我感到震惊的一个问题是,在迁移过程中,主键在联接表上的位置不太正确,但这可能不是问题,因为数据库已经存在。使用这种方法加载数据时也有问题。我可能在设置中出错,但在模型中找不到指定的表“[JoinTable]”。确保已正确指定表名。我同意可为空的外键更实用,尤其是在首先使用EF代码时。然而,从关系数据库的角度来说,这两种观点都有争议,例如。但在我的例子中,我需要首先从现有数据库中对代码进行反向工程。您的解决方案不像edmx方法那样表示模型。我从来没有说过我的解决方案像edmx那样表示模型。我说的是,在我的心里