Vb.net 应用于edmx实体数据模型时,LINQ中的自连接失败
我的EF模型中有以下两个表。一个设备可能有零次、一次或多次数据校准 表“设备”:此表包含设备。主键是等轴面Vb.net 应用于edmx实体数据模型时,LINQ中的自连接失败,vb.net,entity-framework,linq,edmx,Vb.net,Entity Framework,Linq,Edmx,我的EF模型中有以下两个表。一个设备可能有零次、一次或多次数据校准 表“设备”:此表包含设备。主键是等轴面 Id | equipoId | Description 1 9474 2 9473 3 9475 表'CalibracionVerification':此表包含每个设备的校准数据(设备数据校准)。主键是Id Id | equipoId | magnitudId | fechaPrevista 1 9474 0402
Id | equipoId | Description
1 9474
2 9473
3 9475
表'CalibracionVerification':此表包含每个设备的校准数据(设备数据校准)。主键是Id
Id | equipoId | magnitudId | fechaPrevista
1 9474 0402 2020-05-01 00:00:00.000
2 9474 0808 2020-01-01 00:00:00.000
3 9474 0101 2019-12-19 00:00:00.000
4 9473 2001 2018-02-08 00:00:00.000
5 9473 1901 2019-05-23 00:00:00.000
6 9473 1901 2017-08-17 00:00:00.000
7 9472 0808 2020-11-11 00:00:00.000
8 9472 0101 2019-01-01 00:00:00.000
我需要迭代表Equipo中的每个设备,并对每个设备执行以下步骤:
Dim eq = db.Equipo
For Each equipo As Equipo In eq
Dim fechaPrevista As DateTime? =
(From c In equipo.CalibracionVerificacion
Join c2 In (From c3 In equipo.CalibracionVerificacion
Where c3.equipoId = equipo.equipoId AndAlso Not (String.IsNullOrWhiteSpace(c3.magnitudId))
Group c3 By c3.magnitudId Into cgroup = Group
Select New With
{
Key .MagnitudID = magnitudId,
Key .MaxDate = cgroup.Max(Function(x) x.fechaPrevista)
}
) On New With {.JoinProperty1 = c.magnitudId, .JoinProperty2 = c.fechaPrevista} Equals
New With {.JoinProperty1 = c2.MagnitudID, .JoinProperty2 = c2.MaxDate}
Where c.equipoId = equipo.equipoId
Select c).Min(Function(d) d.fechaPrevista))
// Do something with fechaPrevista
Next
通过直接指向数据库,我检查了LINQPad 5中相同的LINQ表达式,它工作正常
例如,考虑到上表,对于equipoId=9474,我希望获得最早的日期和时间,即2019-12-19 00:00:00.000,但由于fechaPrevista,我什么也得不到
因为我无法调试上面的LINQ表达式,所以我将查询分成了几个部分。我一直在调试上面的LINQ表达式,分为两部分:内部LINQ表达式和外部LINQ表达式。对于以下内部Linq表达式:(假设在本例中equipo.equipoId=9474):
。。。我得到了正确的结果。它正在工作并返回以下结果:
因此,内部LINQ表达式工作正常。问题在于外部LINQ表达式,自连接失败,结果是什么也不返回。我不明白为什么。有什么想法吗
基本上,翻译成SQL Server的LINQ表达式是(例如,为了简化,一个Equaloid将是):
使用LINQ时,声明式思考(即,根据期望的结果)比强制式思考(即,控制流)更有帮助。据我所知,最终您希望迭代具有以下属性/字段的resultset:
- 等轴面
- Magnitude
- 第一费查普列维斯塔酒店
- 最后的费查普雷维斯塔
Dim data = db.CalibracionVerificacion
Dim qry = (From item in data group by grp = New With {Key item.equipoId, Key item.magnitudId} into finalGrp = Group
Select New With
{
.equipoId = grp.equipoId,
.magnitudId = grp.magnitudId,
.firstFechaPrevista = finalGrp.Min(function(g) g.fechaPrevista),
.lastFechaPrevista = finalGrp.Max(function(g) g.fechaPrevista)
}).ToList
For each item in qry
'do something
next
不,没有两个fechaPrevista(第一个和最后一个)。只有一个fechaPrevista。在CalibracionVerification实体中,一个设备(Equaloid)可能有多个震级(magnitude)。在该示例中,同一设备没有重复的震级,但可能有。对于每个设备,我按震级分组并获取最新的日期时间(fechaPrevista)。例如,对于设备9474,我获取每个震级的最新日期时间:(04022020-05-01 00:00:00.000),(08082020-01-01 00:00:00.000),(01012019-12-19 00:00:00.000)在这组数据中,我得到了最早的日期时间(fechaPrevista),在本例中是“2019-12-19 00:00:00.000”。我对其余设备也这样做:9473和9472正如我所观察到的,内部linq表达式工作正常,但外部linq表达式应用连接失败。连接失败,但我不知道原因。请参阅最后更新的帖子。我在linq中尝试执行的操作与转换为SQL的操作相同服务器(为了简化,我只举了一个设备的例子)。
-- Region Parameters
DECLARE @p0 Int = 9474
DECLARE @p1 Int = 9474
-- EndRegion
SELECT MIN([t0].[fechaPrevista]) AS [value]
FROM [eq].[CalibracionVerificacion] AS [t0]
INNER JOIN (
SELECT MAX([t1].[fechaPrevista]) AS [value], [t1].[magnitudId]
FROM [eq].[CalibracionVerificacion] AS [t1]
WHERE [t1].[equipoId] = @p0
GROUP BY [t1].[magnitudId]
) AS [t2] ON ([t0].[magnitudId] = [t2].[magnitudId]) AND ([t0].[fechaPrevista] = [t2].[value])
WHERE [t0].[equipoId] = @p1
Dim data = db.CalibracionVerificacion
Dim qry = (From item in data group by grp = New With {Key item.equipoId, Key item.magnitudId} into finalGrp = Group
Select New With
{
.equipoId = grp.equipoId,
.magnitudId = grp.magnitudId,
.firstFechaPrevista = finalGrp.Min(function(g) g.fechaPrevista),
.lastFechaPrevista = finalGrp.Max(function(g) g.fechaPrevista)
}).ToList
For each item in qry
'do something
next