加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 在Linq和Entity Framework中使用内联表值函数

发布时间:2020-12-16 01:27:51 所属栏目:百科 来源:网络整理
导读:我在SQL Server中创建了一个内联表值函数(ITVF),它返回一个值表(为了讨论的目的简化了查询): CREATE FUNCTION dbo.VehicleRepairStatus()RETURNS TABLEAS RETURN SELECT VehicleID,CurrentStatus FROM VehicleRepairHistory ... 我可以在查询中引用: SELEC
我在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)
...

请参阅链接中的后续帖子的答案,以便正确实施相关查询方案.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读