c# - EF Core 一对多与 IQueryable

标签 c# linq entity-framework-core

我正在尝试在基于表的模型(Driver)和基于 SQL 查询的模型(DriverSchedule)之间创建一对多关系).

我很难让这个架构发挥作用。

驱动模型:

[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>();

产生一个错误:

The query type 'DriverSchedule' cannot be added to the model because an entity type with the same name already exists.

** 编辑 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);

更改查询接口(interface):

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();

失败并出现此错误:

The property 'Driver' is not a navigation property of entity type 'DriverSchedule'. The 'Include(string)' method can only be used with a '.' separated list of navigation property names.

**/编辑0 **

** 编辑 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

**/编辑1 **

我错过了什么?

最佳答案

那是因为您已经有一个名为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>");

建议,永远不要使用实体类作为模型。

关于c# - EF Core 一对多与 IQueryable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56799536/

相关文章:

c# - LINQ 在插入中将 "0"转换为 NULL

c# - 基于属性值创建动态 Linq 查询

entity-framework-core - EFCore将2个实体映射到同一张表

c# - 如何深度复制强类型集合的成员

c# - 如何使用.NET 远程扩展环境变量?

c# - 我如何将 Linq var 转换为列表

c# - 数据库首次迁移 EF Core

c# - C# 如何在另一个窗体中打开一个新窗口窗体

c# - 空发布请求(.Net Core 3.1)

c# - Entity Framework 核心存储过程