c# – 在Linq和Entity Framework中使用内联表值函数
我在SQL Server中创建了一个内联表值函数(ITVF),它返回一个值表(为了讨论的目的简化了查询):
CREATE FUNCTION dbo.VehicleRepairStatus() RETURNS TABLE AS RETURN SELECT VehicleID,CurrentStatus FROM VehicleRepairHistory ... 我可以在查询中引用: SELECT v.ID,v.Name,r.CurrentStatus FROM Vehicle v LEFT OUTER JOIN dbo.VehicleRepairStatus() r on v.ID = r.VehicleID 我希望能够在Linq查询中使用它: var vehicles = await _databaseContext.Vehicles .Join() // join ITVF here? .Where(v => v.Type == 'Bus' ) .OrderBy(v => v.Name) .ToAsyncList(); 在某些时候,我可能会更改ITVF以包含一个参数: CREATE FUNCTION dbo.VehicleRepairStatus(@id AS INT) RETURNS TABLE AS RETURN SELECT VehicleID,CurrentStatus FROM VehicleRepairHistory ... WHERE VehicleID = @id 并称之为标量: SELECT v.ID,(SELECT val FROM dbo.VehicleRepairStatus(v.ID)) AS CurrentStatus FROM Vehicle v Linq查询: var vehicles = await _databaseContext.Vehicles .Select( ) // call ITVF here? .Where(v => v.Type == 'Bus' ) .OrderBy(v => v.Name) .ToAsyncList(); 两种方法都可以吗? 解决方法
是的,可以通过使用引入
query types的EF Core 2.1来实现.以下是必需的步骤:
首先,创建一个类来保存TVF记录(使用正确的数据类型更新它): public class VehicleRepairStatus { public int VehicleID { get; set; } public int CurrentStatus { get; set; } } 然后在OnModelCreating中注册它: modelBuilder.Query<VehicleRepairStatus>(); 然后使用Query和FromSql方法的组合从db上下文中公开它: public IQueryable<VehicleRepairStatus> VehicleRepairStatus(int id) => Query<VehicleRepairStatus>().FromSql($"select * from VehicleRepairStatus({id})"); 就这样. 现在,您可以在LINQ查询中使用它,就像任何其他IQueryable< T>一样.返回方法,例如: from v in db.Vehicles from r in db.VehicleRepairStatus(v.ID) select new { v.ID,r.CurrentStatus } FromSql方法中的“select”使其可组合,因此整个查询被转换为SQL并执行服务器端. 更新:实际上,当用作相关子查询时,这不起作用,如上例所示(参见Reference to an ITVF raises a “second operation started on this context before a previous operation completed” exception).它只能在传递常量/变量参数时使用 from r in db.VehicleRepairStatus(123) ... 请参阅链接中的后续帖子的答案,以便正确实施相关查询方案. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |