[英]Entity Framework Many to Many - Cannot get data
I have introduced a many to many relationship between two of my existing tables. 我已经介绍了两个现有表之间的多对多关系。 For this, I have added a third table, which contains only the Ids of the other two tables. 为此,我添加了第三个表,其中只包含其他两个表的ID。
Since I am using EF, I have also added 由于我使用EF,我还添加了
public virtual List<EntityOne> EntityOnes
in EntityTwo public virtual List<EntityOne> EntityOnes
中的public virtual List<EntityOne> EntityOnes
EntityOnes
and 和
public virtual List<EntityTwo> EntityTwos
in EntityOne. public virtual List<EntityTwo> EntityTwos
中的public virtual List<EntityTwo> EntityTwos
EntityTwos。
However, with this, when I get the EntityTwo object, it does not contain the associated EntityOne object. 但是,有了这个,当我获得EntityTwo对象时,它不包含关联的EntityOne对象。 The list has a count of zero, even though the data is there in the tables. 该列表的计数为零,即使表中存在数据。
Am I missing something here? 我在这里错过了什么吗? Is there anything else, I need to do? 还有什么我需要做的吗?
Not sure,if this is relevant, but I have also this in OnModelCreation 不确定,如果这是相关的,但我在OnModelCreation中也有这个
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<EntityOne>().
HasMany(p => p.EntityTwos).
WithMany(a => a.EntityOnes).
Map(
m =>
{
m.MapLeftKey("EntityTwoId");
m.MapRightKey("EntityOneId");
m.ToTable("EntityRelations");
});
////Make sure a context is not created by default.
}
Try this: 尝试这个:
public partial class One
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public virtual int Id { get; set; }
private ICollection<OneTwo> _oneTwos;
public virtual ICollection<OneTwo> OneTwos
{
get { return _oneTwos ?? (_oneTwos = new List<OneTwo>()); }
set { _oneTwos = value; }
}
}
public partial class Two
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public virtual int Id { get; set; }
private ICollection<OneTwo> _oneTwos;
public virtual ICollection<OneTwo> OneTwos
{
get { return _oneTwos ?? (_oneTwos = new List<OneTwo>()); }
set { _oneTwos = value; }
}
}
Add navigation properties to the join class: 将导航属性添加到连接类:
public partial class OneTwo
{
public virtual int OneId { get; set; }
public virtual int TwoId { get; set; }
public virtual One One { get; set; }
public virtual Two Two { get; set; }
}
Add composite key to the join class and configure relationships: 将组合键添加到连接类并配置关系:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<OneTwo>() // composite primary key
.HasKey(p => new { p.OneId, p.TwoId });
modelBuilder.Entity<OneTwo>()
.HasRequired(a => a.One)
.WithMany(c => c.OneTwos)
.HasForeignKey(fk => fk.OneId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<OneTwo>()
.HasRequired(a => a.Two)
.WithMany(c => c.OneTwos)
.HasForeignKey(fk => fk.TwoId)
.WillCascadeOnDelete(false);
// TODO: handle orphans when last asociation is deleted
}
An alternative strategy is to configure EF relationships via EntityTypeConfiguration<>. 另一种策略是通过EntityTypeConfiguration <>配置EF关系。 The following many-to-many relationship implementation demonstrates that approach: 以下多对多关系实现演示了这种方法:
public partial class City
{
public virtual int Id { get; set; }
private ICollection<CountyCity> _countiesCities;
public virtual ICollection<CountyCity> CountiesCities
{
get { return _countiesCities ?? (_countiesCities = new List<CountyCity>()); }
set { _countiesCities = value; }
}
}
public partial class County
{
public virtual int Id { get; set; }
private ICollection<CountyCity> _countiesCities;
public virtual ICollection<CountyCity> CountiesCities
{
get { return _countiesCities ?? (_countiesCities = new List<CountyCity>()); }
set { _countiesCities = value; }
}
}
public partial class CountyCity
{
public virtual int CountyId { get; set; }
public virtual int CityId { get; set; }
public virtual County County { get; set; }
public virtual City City { get; set; }
}
public class CountyCityConfiguration : IEntityTypeConfiguration<CountyCity>
{
public void Map(EntityTypeBuilder<CountyCity> builder)
{
// Table and Schema Name declarations are optional
//ToTable("CountyCity", "dbo");
// composite primary key
builder.HasKey(p => new { p.CountyId, p.CityId });
builder.HasOne(pt => pt.County)
.WithMany(p => p.CountiesCities)
.HasForeignKey(pt => pt.CountyId)
.OnDelete(DeleteBehavior.Restrict);
builder.HasOne(pt => pt.City)
.WithMany(t => t.CountiesCities)
.HasForeignKey(pt => pt.CityId)
.OnDelete(DeleteBehavior.Restrict);
// TODO: handle orphans when last association is deleted
}
}
You may configure the composite key and relationships using EntityTypeConfiguration<> as the previous code demonstrates. 您可以使用EntityTypeConfiguration <>配置组合键和关系,如前面的代码所示。
EntityTypeConfiguration<> has not yet been migrated. 尚未迁移EntityTypeConfiguration <>。 However, it is on the roadmap for the next release. 但是,它是下一个版本的路线图。
In the meantime, you can employ the temporary pattern suggested by the EF team , or one of the patterns discussed this rather lengthy StackOverflow post discussing entity configuration in Entity Framework 7 . 与此同时,您可以使用EF团队建议的临时模式 ,或者讨论这个相当冗长的StackOverflow帖子讨论实体框架7中的实体配置的模式之一。
I implemented the pattern posted by Cocowalla in the lengthy discussion prior to reading the EF Team post. 在阅读EF团队帖子之前,我在冗长的讨论中实施了Cocowalla发布的模式。 The source code for my workaround is available in this GitHub repository . 我的解决方法的源代码可在此GitHub存储库中找到 。
namespace Dna.NetCore.Core.DAL.EFCore.Configuration.Temporary.Cocowalla
{
// attribute: https://stackoverflow.com/questions/26957519/ef-7-mapping-entitytypeconfiguration/35373237#35373237
public interface IEntityTypeConfiguration<TEntityType> where TEntityType : class
{
void Map(EntityTypeBuilder<TEntityType> builder);
}
}
Here is my implementation of that pattern: 这是我对该模式的实现:
namespace Dna.NetCore.Core.DAL.EFCore.Configuration.Common
{
public class StateOrProvinceConfiguration : IEntityTypeConfiguration<StateOrProvince>
{
public void Map(EntityTypeBuilder<StateOrProvince> builder)
{
// EF Core
builder.HasOne(p => p.Country).WithMany(p => p.StateOrProvinces).HasForeignKey(s => s.CountryId).OnDelete(DeleteBehavior.Cascade);
builder.HasMany(d => d.Cities).WithOne().OnDelete(DeleteBehavior.Cascade);
builder.HasMany(d => d.Counties).WithOne().OnDelete(DeleteBehavior.Cascade);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.