简体   繁体   English

实体框架多对多 - 无法获取数据

[英]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: 以下多对多关系实现演示了这种方法:

City.cs City.cs

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; }
    }
}

County.cs County.cs

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; }
    }
}

CountyCity.cs CountyCity.cs

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; }
}

CountyCityConfiguration.cs (EF 6 implementation) CountyCityConfiguration.cs(EF 6实施)

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
    }
}

Entity Framework 6 Implementations: 实体框架6实施:

You may configure the composite key and relationships using EntityTypeConfiguration<> as the previous code demonstrates. 您可以使用EntityTypeConfiguration <>配置组合键和关系,如前面的代码所示。

Entity Framework Core Implementations: 实体框架核心实现:

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存储库中找到

IEntityTypeConfiguration.cs IEntityTypeConfiguration.cs

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM