EF Core один-ко-многим с IQueryable - PullRequest
2 голосов
/ 28 июня 2019

Я пытаюсь создать отношение «один ко многим» между моделью на основе таблицы (Driver) и моделью на основе запроса SQL (DriverSchedule).

I 'Мне трудно заставить эту архитектуру функционировать.

Driver модель:

[Table("Drivers")]
public class Driver
{
    [Key]
    [Column("DriverKey")]
    public int ID { get; set; }
    ...
    public virtual ICollection<DriverSchedule> DriverSchedules { get; set; }
}

DriverSchedule модель:

public class DriverSchedule
{
    public int DriverID { get; set; }  // foreign key
    public DateTime Date { get; set; }
    public bool IsScheduled { get; set; }
    public virtual Driver Driver { get; set; }
}

VendorDbContext контекст:

public class VendorDbContext : DbContext
{
    ...
    public DbSet<Driver> Drivers { get; set; }
    ...

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<DriverSchedule>().HasKey(table => new { table.DriverID, table.Date });
        modelBuilder.Entity<Driver>().HasMany(d => d.DriverSchedules).WithOne(s => s.Driver);
        ...
        modelBuilder.Query<DriverSchedule>();
    }

    public IQueryable<DriverSchedule> DriverSchedules(DateTime startingDate, DateTime endingDate) =>
        Query<DriverSchedule>().FromSql("<SQL>");
}

Просмотр:

@model IEnumerable<Driver>
...
@foreach (var item in Model)
{
    <tr>
        <td>@(item.Name)</td>
        <td>@(item.ID)</td>
        <td><ul>
            foreach (var driverSchedule in item.DriverSchedules)
            {
                <li>@(driverSchedule.ToString("MM/dd/yy") - @(driverSchedule.IsScheduled)</li>
            }
        </ul></td>
    </tr>
}
...

Мой запрос LINQ:

var model = await (
    from driver in _context.Drivers
    join schedule in _context.DriverSchedules(startDate.Date, endDate.Date) on driver.ID equals schedule.DriverID
    orderby driver.LastName, driver.FirstName
    select driver
).Include(x => x.DriverSchedules)
.ToListAsync();

Когда я запускаю код, эта строка:

modelBuilder.Query<DriverSchedule>();

генерируетошибка:

Невозможно добавить тип запроса «DriverSchedule» в модель, поскольку тип сущности с таким именем уже существует.

** edit 0 **

Эта публикация https://msdn.microsoft.com/en-us/magazine/mt847184.aspx предполагает, что мне нужно

Удалить свойство навигации из Driver:

//public virtual ICollection<DriverSchedule> DriverSchedules { get; set; }

Удалить свойство навигации из DriverSchedule:

//public virtual Driver Driver { get; set; }

Удалите определения отношений из OnModelCreating:

// modelBuilder.Entity<DriverSchedule>().HasKey(table => new { table.DriverID, table.Date });
// modelBuilder.Entity<Driver>().HasMany(d => d.DriverSchedules).WithOne(s => s.Driver);

Измените интерфейс запроса:

IQueryable<DriverSchedule> DriverSchedules(DateTime startingDate, DateTime endingDate) =>
        Query<DriverSchedule>() ...

Определите связь между запросом илицо:

modelBuilder.Query<DriverSchedule>().HasOne<Driver>().WithMany();

Затем переписать запрос:

model = await _context.DriverSchedules(startDate.Date, endDate.Date)
           .Include("Driver")
           .ToListAsync();

Что не получается с этой ошибкой:

Свойство «Драйвер» не является свойством навигациитипа объекта «DriverSchedule».Метод «Включить (строка)» можно использовать только с «.»разделенный список имен свойств навигации.

** / edit 0 **

** edit 1 **

SELECT  m.DriverID, c.Date
        ,CAST( CASE WHEN COUNT(CASE WHEN c.date <> CAST(m.StartTime AS DATE) THEN NULL ELSE m.MovementID end)>0 THEN 1 ELSE 0 END AS BIT) IsScheduled
FROM    dbo.Calendar c
CROSS APPLY vMovements m
WHERE  1 = 1
AND   c.date BETWEEN {startingDate} AND {endingDate}
AND   m.DriverID IS NOT NULL
GROUP BY c.date, m.DriverID

** / edit 1 **

Чего мне не хватает?

1 Ответ

1 голос
/ 28 июня 2019

Это потому, что у вас уже есть объект с именем DriverSchedule

проблема здесь:

modelBuilder.Entity<DriverSchedule>();
modelBuilder.Query<DriverSchedule>(); // wrong. 

создать другую модель для получения и отображения результатов данных в методе DriverSchedules. Итак:

public class Driversched
{
    public int DriverID { get; set; }  // foreign key
    public DateTime Date { get; set; }
    public bool IsScheduled { get; set; }
    public virtual Driver Driver { get; set; }
}

тогда:

modelBuilder.Query<Driversched>();

И наконец:

 public IQueryable<Driversched> DriverSchedules(DateTime startingDate, DateTime endingDate) =>
        Query<DriverSchedule>().FromSql("<SQL>");

совет, никогда не используйте класс сущности в качестве модели.

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