LINQ для многих ко многим в EF Core 2 - PullRequest
0 голосов
/ 23 мая 2018

Я некоторое время искал в google и stackoverflow, и да, я нашел много статей на эту тему, но все еще не могу понять, что я делаю неправильно.

Проблема: у меня естьТаблица «link» (многие ко многим) между тремя таблицами: - check - car - gate

Мой класс 'link' выглядит следующим образом:

public class CheckCarGate
{
    public int CheckId { get; set; }
    public Check Check{ get; set; }

    public int CarId { get; set; }
    public Car Car{ get; set; }

    public int GateId { get; set; } 
    public Gate Gate { get; set; } 
}

DbContext:

public virtual DbSet<Car> Cars{ get; set; }
public virtual DbSet<Gate> Gates { get; set; }
public virtual DbSet<Check> Checks{ get; set; }

// Ключ:

protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<CheckCarGate>().HasKey(p => new { p.CheckId, p.CarId, p.GateId });
    }

Я следовал этой документации https://docs.microsoft.com/en-us/ef/core/modeling/relationships#many-to-many при создании моделей.CheckCarGate - это свойство навигации в моделях сущностей.Например,

public class Gate
{
    public int GateId { get; set; }
    public string Descr { get; set; }

    public ICollection<CheckCarGate> CheckCarGates { get; set; }
}

Код впервые создал эту таблицу в базе данных.Сейчас я пытаюсь выбрать все чеки со всеми воротами для одного конкретного CarId.

Я пробовал что-то вроде этого:

var masterlist = _context.Checks.Where(p => p.CheckCarGate.Any(x => x.CarId == 12));

или:

var masterlist = _context.Checks
                .Include(p => p.CheckCarGate)
                .ThenInclude(p=>p.Gate)
                .Include(p=>p.CheckCarGate)
                .ThenInclude(p=>p.Car);

// Редактировать: Извините, что не предоставил достаточно информации!Терпите меня ...

Может ли кто-нибудь указать мне правильное направление?

Заранее большое спасибо!

N.

Ответы [ 3 ]

0 голосов
/ 24 мая 2018

В вашем OnModelCreating (...) должно быть больше, определяющее отношение

protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<CheckCarGate>().HasKey(p => new { p.CheckId, p.CarId, p.GateId });

        builder.Entity<CheckCarGate>().HasOne(c => c.car)
                                      .WithMany(c => c.check)
                                      .HasForeignKey(k => k.carId)

        ...
    }

Я не уверен, как вы изменили свой запрос после этого, у предоставленной ссылки на документацию не было примераиспользование.

0 голосов
/ 25 мая 2018

Я бросил искать решение LINQ.(2 дня потрачено впустую).

Вместо этого я решил использовать raw sql и сохранить данные в новом объекте.

Кредиты для: https://stackoverflow.com/users/355714/pius и его решение: https://stackoverflow.com/a/46013305/848642

0 голосов
/ 24 мая 2018

Я не уверен, что здесь достаточно информации, чтобы ответить на ваш вопрос;Похоже, что у каждой проверки есть свой чекгейт, что на самом деле не имеет смысла.

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

var out = CheckCarGateTable.Where(t => t.CarID == targetCarID)
          .Select(c => checks.getbyid(c.CheckID))

или, в зависимости от определения вашего класса

var out = CheckCarGateTable.Where(t => t.CarID == targetCarID)
          .Select(c => c.Check))

Сначала мы получаем все CheckCarGates, которые относятся к нашей целевой машине, а затем преобразуем их в проверки с помощью вызова select;out должен иметь тип IEnumerable

и обрабатывать список следующим образом:

foreach (Check c in out)
{
     proc(c);
}

Это лучшее, что я могу сделать с предоставленной информацией.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...