我正在尝试在基于表的模型(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/