Entity Framework 关系 0..1 与 1..* 返回 link
Entity Framework relationship 0..1 with 1..* back link
我的 Entity Framework POCO 类 中有两个对象,名为 Lifeboat 和 Sighting
Sighting 与 Lifeboat 有 1..* 关系,这似乎工作正常(SightingLifeboats link table
我现在还需要反向引用该关系,所以我需要从救生艇到瞄准镜的 link,这将是 0..*
我试过反其道而行之,并尝试制作一个虚拟的,但这没有奏效,也许我需要更流畅的编码?
我的救生艇Class:
public class Lifeboat : EntityBase
{
public Lifeboat()
{
Sightings = new List<Sighting>();
}
public string CurrentName { get; set; }
//A Lifeboat Ownes 0:* Sightings
public List<Sighting> Sightings { get; set; }
//public virtual Sighting Sightings { get; set; }
//Called from Context Class OnModelCreating
public static void LifeboatEntityConfiguration(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Lifeboat>().HasMany(x => x.Sightings).WithMany();
}
}
和瞄准 Class
public class Sighting : EntityBase
{
public Sighting()
{
Lifeboats = new List<Lifeboat>();
TimeSeen = DateTime.Now.Date;
}
public string Location { get; set; }
//A Sighting has 1..* Lifeboats (Not Owned)
public List<Lifeboat> Lifeboats { get; set; }
//public virtual Lifeboat Lifeboat { get; set; }
public static void SightingEntityConfiguration(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Sighting>().HasMany(x => x.Lifeboats).WithMany();
}
}
这不是在 Lifeboat
和 Sighting
之间配置多对多关系的正确方法。如果删除已有的 Fluent Api 配置,默认情况下,EF 将创建第三个连接 table、SightingLifeboats
,它将由 table 的 PK 组成秒。那是因为您在每个实体中都有一个集合导航 属性。但是您可以使用 Fluent Api:
明确配置该关系
modelBuilder.Entity<LifeBoat>()
.HasMany<Sighting >(l => l.Sightings)
.WithMany(s => s.LifeBoats)
.Map(cs =>
{
cs.MapLeftKey("LifeBoatRefId");
cs.MapRightKey("SightingId");
cs.ToTable("SightingLifeboats");
});
这样您就可以更改联结点的名称 table 并指定 FK 属性 名称,以防您需要更改它们。
另一件事,我建议将您的集合属性更改为 virtual
。如果您将所有属性设置为 virtual
,则 EF 将在运行时生成代理 类,该代理源自您的 POCO 类,这些代理允许 EF 实时了解更改,而不必捕获对象的原始值,然后在保存时扫描更改。
我的 Entity Framework POCO 类 中有两个对象,名为 Lifeboat 和 Sighting
Sighting 与 Lifeboat 有 1..* 关系,这似乎工作正常(SightingLifeboats link table
我现在还需要反向引用该关系,所以我需要从救生艇到瞄准镜的 link,这将是 0..*
我试过反其道而行之,并尝试制作一个虚拟的,但这没有奏效,也许我需要更流畅的编码?
我的救生艇Class:
public class Lifeboat : EntityBase
{
public Lifeboat()
{
Sightings = new List<Sighting>();
}
public string CurrentName { get; set; }
//A Lifeboat Ownes 0:* Sightings
public List<Sighting> Sightings { get; set; }
//public virtual Sighting Sightings { get; set; }
//Called from Context Class OnModelCreating
public static void LifeboatEntityConfiguration(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Lifeboat>().HasMany(x => x.Sightings).WithMany();
}
}
和瞄准 Class
public class Sighting : EntityBase
{
public Sighting()
{
Lifeboats = new List<Lifeboat>();
TimeSeen = DateTime.Now.Date;
}
public string Location { get; set; }
//A Sighting has 1..* Lifeboats (Not Owned)
public List<Lifeboat> Lifeboats { get; set; }
//public virtual Lifeboat Lifeboat { get; set; }
public static void SightingEntityConfiguration(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Sighting>().HasMany(x => x.Lifeboats).WithMany();
}
}
这不是在 Lifeboat
和 Sighting
之间配置多对多关系的正确方法。如果删除已有的 Fluent Api 配置,默认情况下,EF 将创建第三个连接 table、SightingLifeboats
,它将由 table 的 PK 组成秒。那是因为您在每个实体中都有一个集合导航 属性。但是您可以使用 Fluent Api:
modelBuilder.Entity<LifeBoat>()
.HasMany<Sighting >(l => l.Sightings)
.WithMany(s => s.LifeBoats)
.Map(cs =>
{
cs.MapLeftKey("LifeBoatRefId");
cs.MapRightKey("SightingId");
cs.ToTable("SightingLifeboats");
});
这样您就可以更改联结点的名称 table 并指定 FK 属性 名称,以防您需要更改它们。
另一件事,我建议将您的集合属性更改为 virtual
。如果您将所有属性设置为 virtual
,则 EF 将在运行时生成代理 类,该代理源自您的 POCO 类,这些代理允许 EF 实时了解更改,而不必捕获对象的原始值,然后在保存时扫描更改。