【问题标题】:Entity Framework Core always returns an empty list related tablesEntity Framework Core 总是返回一个空列表相关表
【发布时间】:2021-01-14 13:45:13
【问题描述】:

我正在使用 .Net Core 5.0 和 Entity Framework,但我遇到了 .Include() 问题,它返回的是空列表。

以下是课程:

public class Contact
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName { get; set; }
    public string Address { get; set; }
    public string Email { get; set; }
    public string MobilePhoneNumber { get; set; }

    public ICollection<ContactSkill> ContactSkills { get; set; }
}

public class Skill
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int ExpertiseLevel { get; set; }

    public ICollection<ContactSkill> ContactSkills { get; set; }
}

public class ContactSkill
{
    public int Id { get; set; }
    public int ContactId { get; set; }
    public int SkillId { get; set; }

    public Contact Contact { get; set; }
    public Skill Skill { get; set; }
}

还有 DbContext:

public class APIContext : DbContext
{
    public APIContext(DbContextOptions<APIContext> options) : base(options)
    {
    }

    public DbSet<Contact> Contacts { get; set; }
    public DbSet<Skill> Skills { get; set; }
    public DbSet<ContactSkill> ContactSkills { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Contact>().ToTable("Contacts");
        modelBuilder.Entity<Skill>().ToTable("Skills");
        modelBuilder.Entity<ContactSkill>().ToTable("ContactSkills");
    }
}

联系人和技能都正确填写,但是当我添加包含时,它是空的:

        var contact = await _context.Contacts
            .Include(c => c.ContactSkills)
                .ThenInclude(cs => cs.Skill)
            .AsNoTracking()
            .FirstOrDefaultAsync(m => m.Id == id);

DbInitializer.cs:

    public static void Initialize(APIContext context)
    {
        context.Database.EnsureCreated();

        // Look for any contacts.
        if (context.Contacts.Any())
        {
            return;   // DB has been seeded
        }

        var contacts = new Contact[]
        {,
        new Contact{ FirstName = "Sam", LastName = "Gamegi", FullName = "Sam Gamegi", Address = "The Shire", Email = "frodon.baggins@shire.middleearth", MobilePhoneNumber = "+11 0 98 76 54 32"  },
            new Contact{ FirstName = "Samus", LastName = "Samus Aran", FullName = "Samus Aran", Address = "Space", Email = "samus.aran@metroid.com", MobilePhoneNumber = "+66 1 23 45 76 90"  },
        new Contact{ FirstName = "Frodon", LastName = "Baggins", FullName = "Frodon Baggins", Address = "The Shire", Email = "frodon.baggins@shire.middleearth", MobilePhoneNumber = "+11 0 98 76 54 32"  },
        };

        // Look for any skills.
        if (context.Skills.Any())
        {
            return;   // DB has been seeded
        }

        var skills = new Skill[]
        {
            new Skill{ Name = ".Net Framework", ExpertiseLevel = 75},
            new Skill{ Name = "SQL", ExpertiseLevel = 80},
            new Skill{ Name = "Bounty Hunter", ExpertiseLevel = 100},
            new Skill{ Name = "Ring Bearer", ExpertiseLevel = 100}
        };

        foreach (var s in skills)
        {
            context.Skills.Add(s);
        }
        context.SaveChanges();

        // Look for any contact's skills.
        if (context.ContactSkills.Any())
        {
            return;   // DB has been seeded
        }

        var contactSkills = new ContactSkill[]
        {
            new ContactSkill{ ContactId = 1, SkillId = 1},
            new ContactSkill{ ContactId = 1, SkillId = 2},
            new ContactSkill{ ContactId = 2, SkillId = 3},
            new ContactSkill{ ContactId = 3, SkillId = 4},
        };

        foreach (var cs in contactSkills)
        {
            context.ContactSkills.Add(cs);
        }
        context.SaveChanges();
    }

我想我的数据库已创建,因为我看到了数据,但我在 SQL Explorer 中看不到我的数据库。

【问题讨论】:

  • 您是否发布了真实的 dbcontext 或者这只是一个示例?
  • 我认为您需要为 ICollection 属性添加 virtual 关键字或在 onModelCreating 函数中配置多对多关系。这将帮助您配置多对多关系。 learnentityframeworkcore.com/configuration/…
  • 您的.ThenInclude 肯定没有正确使用。你能把它删掉,看看ContactSkills 是不是还是空的吗?
  • @Sergey:是的,它是完整的 DbContext。我正在对此进行试验,第一次从头开始创建 API。
  • @AbdulG : 试过了,列表还是空的。

标签: asp.net-core entity-framework-core


【解决方案1】:

尝试使用此代码。它在 Visual Studio 中进行了测试。

public class Contact

{
    public Contact()
    {
        ContactSkills = new HashSet<ContactSkill>();
    }
    [Key]
    public int Id { get; set; }
    [Required]
    public string LastName { get; set; }
    [Required]
    public string FirstName { get; set; }
  
    public string FullName { get; set; }
    public string Address { get; set; }
    public string Email { get; set; }
    public string MobilePhoneNumber { get; set; }
    [InverseProperty(nameof(ContactSkill.Contact))]
    public virtual ICollection<ContactSkill> ContactSkills { get; set; }
}


public class Skill
{
    public Skill()
    {
        ContactSkills = new HashSet<ContactSkill>();
    }
    [Required]
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    public int ExpertiseLevel { get; set; }
    [InverseProperty(nameof(ContactSkill.Skill))]
    public virtual ICollection<ContactSkill> ContactSkills { get; set; }
}

public class ContactSkill
{
    [Key]
    public int Id { get; set; }

    public int ContactId { get; set; }

    [ForeignKey(nameof(ContactId))]
    [InverseProperty(nameof(ContactSkill.Contact.ContactSkills))]
    public virtual Contact Contact { get; set; }

    public int SkillId { get; set; }

    [ForeignKey(nameof(SkillId))]
    [InverseProperty(nameof(ContactSkill.Contact.ContactSkills))]
    public virtual Skill Skill { get; set; }
}


public class ApiContext : DbContext
{
    public ApiContext()
    {
    }

    public ApiContext(DbContextOptions<ApiContext> options)
        : base(options)
    {
    }
    public DbSet<Contact> Contacts { get; set; }
    public DbSet<Skill> Skills { get; set; }
    public DbSet<ContactSkill> ContactSkills { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
            if (!optionsBuilder.IsConfigured)
            {
            }
//Use your connection string if it is not configured in Startup file. 
//optionsBuilder.UseSqlServer(@"Server=localhost;Database=Contacts;Trusted_Connec//tion=True;");
    }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ContactSkill>(entity =>
        {
            entity.HasOne(d => d.Contact)
                .WithMany(p => p.ContactSkills)
                .HasForeignKey(d => d.ContactId)
                .OnDelete(DeleteBehavior.ClientSetNull)
                .HasConstraintName("FK_ContactSkill_Contact");

            entity.HasOne(d => d.Skill)
                .WithMany(p => p.ContactSkills)
                .HasForeignKey(d => d.SkillId)
                .HasConstraintName("FK_ContactSkill_Skill");
        });

    }

}

【讨论】:

  • 试过但没有用。如果我将您的 OnConfiguring 部分放在 APIContext 中,则会出现 Win32 错误。
  • 你不需要使用我的配置。我用它在我的电脑上创建 Db。您必须使用连接字符串并将此代码迁移到数据库。
  • 如果我删除配置,包含列表仍然是空的:/
  • 您是否使用此数据库上下文创建了新数据库?
  • 我用创建数据库的代码更新了问题
猜你喜欢
  • 2019-11-11
  • 1970-01-01
  • 2017-04-13
  • 2019-12-02
  • 1970-01-01
  • 1970-01-01
  • 2019-02-05
  • 2022-12-10
  • 2022-08-02
相关资源
最近更新 更多