我有以下SQL查询,由于该查询中有更多条件,因此受到一些限制,我必须将该查询转换为LINQ。
SELECT
sh.BarCode
FROM
Bars AS sh
INNER JOIN BarDetail AS detail ON
detail.BarCode = sh.BarCode
AND
detail.IsActive = 1
INNER JOIN BarStatus AS st ON
st.BarCode = sh.BarCode
AND
st.IsActive = 1
到目前为止,我已经在LINQ 完成了这项工作
var queryAble = _context.BarDetail
.Include(x => x.Bar)
.Include(x => x.Bar)
.ThenInclude(y => y.BarStatus)
.Where(x => x.IsActive == true)
.AsQueryable();
我也想在barstatus
上应用条件;条件是CCD_ 2和CCD_。我做不到。
我不想用DbCommand
作为原始SQL,我想只使用Linq-to-Entities来完成它。
我该怎么做?也许是这样,但它不起作用
var queryAble = _context.BarDetail
.Include(x => x.Bar)
.Include(x => x.Bar)
.ThenInclude(y => y.BarStatus)
.Where(x => x.IsActive == true && x.Bar.BarStatus[SOMETHING HERE])
.AsQueryable();
这是将SQL直接转换为LINQ。请注意,Include
不是用于构建查询,而是用于加载相关数据。
var query =
from bar in _context.Bar
from detail in bar.Details
where detail.IsActive && bar.IsActive && bar.BarStatus.IsActive
select bar.BarCode;
正如我在评论中所说,虽然您的原始SQL查询工作,但JOIN
子句最好只使用键(或元组(相等而其他谓词应该在WHERE
子句中。遵循该模式不会对您的运行时查询执行计划造成任何更改,但我觉得它与SQL所基于的关系演算保持一致,这也意味着您可以立即检查JOIN
是否正确,因为您总是只使用主键和外键列(它们可能已经被索引了…对吧?(。
因此,您的查询变成:
SELECT
b.BarCode
FROM
Bars AS b
INNER JOIN BarDetail AS d ON d.BarCode = b.BarCode
INNER JOIN BarStatus AS s ON s.BarCode = b.BarCode
WHERE
d.IsActive = 1
AND
s.IsActive = 1
更容易翻译成Linq到实体:
还有:
- 您不需要
.AsQueryable()
调用:从DbContext
的DbSet<T>
创建的所有非物化查询都将是IQueryable<T>
- 由于您具有导航属性,因此不需要手动
Join
IQueryable<String> q = _context.BarCode
// .Include( b => b.BarDetail )
// .Include( b => b.BarStatus )
.Where( b =>
b.BarDetail.IsActive == true
&&
b.BarStatus.IsActive == true
)
.Select( b => b.BarCode );
List<String> list = await q.ToListAsync( cancellationToken ).ConfigureAwait(false);
更新:无b.BarDetail.IsActive == true
我不能直接添加
Include( b => b.BarStatus )
,因为BarStatus
与BarCode
没有直接关系,它与BarDetail
链接。因此,首先我们进入BarDetail
,然后使用barstatus
1 进入BarStatus
您仍然可以手动执行JOIN
:
IQueryable<String> q = _context.BarCode
// .Include( b => b.BarDetail )
// .Include( b => b.BarStatus )
.Join( _context.BarStatus, s => s.BarCode, b => b.BarCode, ( s, b )
=> new { BarStatus = s, BarCode = b, BarDetail = b.BarDetail } )
.Where( t =>
t.BarDetail.IsActive == true
&&
t.BarStatus.IsActive == true
)
.Select( b => b.BarCode );
List<String> list = await q.ToListAsync( cancellationToken ).ConfigureAwait(false);