我的数据库中有一个表TestPack
,此表与表1-N
和Documentation
有InternalWalk
的关系。下面的代码通过从数据库中提取所有测试包并迭代每个测试包来编译测试包状态报告。我的应用程序的架构是数据库托管在Windows
服务器计算机(SQL Server)上,客户端应用程序通过网络运行。因此,下面的代码首先获取所有TestPack的列表,并在每次循环迭代中再次查询Documentation
和InternalWalk
表。这会减慢很多事情。
var AllTestPacks = Project.GetAllTestPacksFromDB();
foreach (var tp in AllTestPacks)
{
var testPack = new TestPackStatus { TestPackNo = tp.test_pack_no };
var documentation = tp.Documentations.LastOrDefault();
if (documentation != null && documentation.status == "Accepted" && documentation.acceptance_date >= cutOffDate)
testPack.Documentation = documentation.ReadinessDate;
var internalWalk = tp.InternalWalks.LastOrDefault();
if (internalWalk != null && internalWalk.status == "Accepted" && internalWalk.acceptance_date >= cutOffDate)
testPack.InterWalks = internalWalk.AcceptanceDate;
StatusData.Add(testPack);
}
我在想是否可以将下面的代码翻译成数据库View
而我只是从View
获取数据,这会显着加快速度。如何将上述代码翻译成View
。
这是我到目前为止所尝试的内容,但我无法实现此LastOrDefault()
。
SELECT dbo.TestPack.test_pack_no, dbo.Documentation.rfi_no, dbo.Documentation.rfi_date, dbo.Documentation.status,
FROM dbo.TestPack INNER JOIN dbo.Documentation ON dbo.TestPack.id = dbo.Documentation.test_pack_id WHERE (dbo.Documentation.status = 'Accepted')
答案 0 :(得分:0)
假设您希望按Documentation
加入“最新”InternalWalk
或test_pack_no
记录并按acceptance_date
排序以区分最新记录,则以下SQL(不包括表变量并替换为您自己的表)可以放入传递@cutoff
作为参数的存储过程中:
declare @TestPack table (test_pack_no int)
insert into @TestPack values (1)
insert into @TestPack values (2)
declare @Documentation table (test_pack_no int, Name varchar(20), status varchar(20), acceptance_date datetime)
insert into @Documentation values (1, 'Doc 1', 'Accepted', '21 Dec 2015')
insert into @Documentation values (1, 'Doc 2', 'Accepted', '22 Dec 2015')
insert into @Documentation values (2, 'Doc 1', 'Non-Accepted', '22 Dec 2015')
insert into @Documentation values (2, 'Doc 2', 'Accepted', '21 Dec 2015')
declare @InternalWalk table (test_pack_no int, Name varchar(20), status varchar(20), acceptance_date datetime)
insert into @InternalWalk values (1, 'Walk 1', 'Accepted', '20 Dec 2015')
insert into @InternalWalk values (1, 'Walk 2', 'Accepted', '21 Dec 2015')
declare @cutoff datetime = '21 dec 2015'
;with cte_Documentation
as
(
select
row_number() over (partition by test_pack_no order by acceptance_date desc) [RN], *
from
@Documentation
where
status='Accepted'
and acceptance_date >= @cutoff
),
cte_InternalWalk
as
(
select
row_number() over (partition by test_pack_no order by acceptance_date desc) [RN], *
from
@InternalWalk
where
status='Accepted'
and acceptance_date >= @cutoff
),
cte_TestPack
as
(
select
tp.*, d.status, d.Name [Doc_Name], d.acceptance_date [Doc_AcceptDate], iw.Name [InternalWalk_Name], iw.acceptance_date [InternalkWalk_AcceptDate]
from
@TestPack tp
left join cte_Documentation d on d.test_pack_no=tp.test_pack_no and d.RN=1
left join cte_InternalWalk iw on iw.test_pack_no=tp.test_pack_no and iw.RN=1
)
select * from cte_TestPack
从您的示例中确切地了解哪些列已过滤并且需要作为结果的一部分。
您只需让EF调用SPROC将截止日期作为参数返回,该参数将返回一个平面结构,然后可以将其转换为您的单个对象TestPack
,Documentation
和{{1 }}