Запрос данных со многими ко многим в .NET Core 2.x - PullRequest
0 голосов
/ 26 февраля 2019

Это примеры объектов:

public class Person
{
    public int Id { get; set; }
    public bool IsCool { get; set; }
    public List<PersonCommunity> Communities { get; set; }
}

public class Community
{
    public int Id { get; set; }
    public bool IsPopular { get; set; }
    public List<PersonCommunity> People { get; set; }
}

public class PersonCommunity
{
    public int PersonId { get; set; }
    public Person Person { get; set; }
    public int CommunityId { get; set; }
    public Community Community { get; set; }
}

Вот как они будут настроены в ApplicationDbContext:

public DbSet<Person> People { get; set; }

public DbSet<Community> Communities { get; set; }

public DbSet<PersonCommunity> PersonCommunities { get; set; }

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

    modelBuilder.Entity<PersonCommunity>()
        .HasKey(e => new { e.PersonId, e.CommunityId });

    modelBuilder.Entity<PersonCommunity>()
        .HasOne(e => e.Person)
        .WithMany(e => e.Communities)
        .HasForeignKey(e => e.PersonId);

    modelBuilder.Entity<PersonCommunity>()
        .HasOne(e => e.Community)
        .WithMany(e => e.People)
        .HasForeignKey(e => e.CommunityId);
}

Теперь я хочу взять:

  • Персона
  • По заданному идентификатору

Но:

  • Этот человек должен быть крутым (IsCool = true)
  • Этот человекдолжен исходить как минимум из одного непопулярного сообщества (IsPopular = false)

Во всех других случаях запрос должен возвращать ноль, даже если в базе данных существует человек с данным Id.Таким образом, запрос только ctx.People.FirstOrDefault(p => p.Id == id) вне таблицы.

Я хочу сделать это максимально оптимизированным и эффективным способом, особенно без загрузки ненужных данных в память программы.

Подсказка. Первоначально мне приходилось запрашивать более 2 млн пользователей, назначенных в более чем 10 тыс. Групп с отношением «многие ко многим», с помощью определенных флагов.И я не могу просто использовать SQL.Это должен быть EF Core.

Я обнаружил множество похожих вопросов, которые решают эту проблему частично или полностью, не удовлетворяя требованиям эффективности, что здесь очень важно.

1 Ответ

0 голосов
/ 26 февраля 2019

Прочитав весь раздел комментариев под вопросом, я публикую ответ От имени Иван Стоев .

Ваш запрос должен быть следующим:

Person person = _context.Peoples.FirstOrDefault(p => p.Id == id && p.IsCool &&
                                 p.Communities.Any(pc => !pc.Community.IsPopular));
...