【发布时间】:2021-09-13 18:03:35
【问题描述】:
我的数据服务中有这个方法,它返回两个字段 DisplayName 和 Version Key。当我查看正在访问服务器的查询时,它是两个 select 语句?有没有更好的方法来编写这个 Linq,所以它只返回我需要的数据?我没有使用toList(),所以我不确定它为什么返回这么多数据。
模型类
public class AgentDto
{
public long Id { get; set; }
public string Name { get; set; }
public Guid? VersionKey { get; set; }
}
数据服务
public IQueryable<Data.Dto.Agent.AgentDto> GetPublishedAgent()
{
var Agent = (from t in UnitOfWork.GetRepository<Template>().Get()
join r in UnitOfWork.GetRepository<Regimen>().Get() on t.Id equals r.TemplateId
join rp in UnitOfWork.GetRepository<RegimenPart>().Get() on r.Id equals rp.RegimenId
join re in UnitOfWork.GetRepository<RegimenEntry>().Get() on rp.Id equals re.RegimenPartId
join a in UnitOfWork.GetRepository<Agent>().Get() on re.AgentVersionKey equals a.VersionKey
where t.IsCurrentVersion && t.Status == 7 && a.IsCurrentVersion && a.IsActive
select new Data.Dto.Agent.AgentDto
{
Name = a.DisplayName,
VersionKey= a.VersionKey
});
Agent = Agent.Distinct();
return Agent;
}
服务器分析器
SELECT DISTINCT [t5].[Id], [t5].[Name], [t5].[Added], [t5].[Modified], [t5].[Deleted], [t5].[IsDeleted], [t5].[RxNormId], [t5].[BrandNames], [t5].[IsFreeText], [t5].[AddedBy], [t5].[ModifiedBy], [t5].[DeletedBy], [t5].[RxNormText], [t5].[NccnTallMan], [t5].[RxNormTallMan], [t5].[IsActive], [t5].[VersionKey], [t5].[VersionNumber], [t5].[IsCurrentVersion], [t5].[value] AS [VersionKey2]
FROM (
SELECT [t4].[Id], [t4].[Name], [t4].[Added], [t4].[Modified], [t4].[Deleted], [t4].[IsDeleted], [t4].[RxNormId], [t4].[BrandNames], [t4].[IsFreeText], [t4].[AddedBy], [t4].[ModifiedBy], [t4].[DeletedBy], [t4].[RxNormText], [t4].[NccnTallMan], [t4].[RxNormTallMan], [t4].[IsActive], [t4].[VersionKey], [t4].[VersionNumber], [t4].[IsCurrentVersion], [t4].[VersionKey] AS [value], [t0].[IsCurrentVersion] AS [IsCurrentVersion2], [t0].[Status]
FROM [dbo].[Templates] AS [t0]
INNER JOIN [dbo].[Regimens] AS [t1] ON [t0].[Id] = [t1].[TemplateId]
INNER JOIN [dbo].[RegimenParts] AS [t2] ON [t1].[Id] = [t2].[RegimenId]
INNER JOIN [dbo].[RegimenEntries] AS [t3] ON [t2].[Id] = [t3].[RegimenPartId]
INNER JOIN [dbo].[Agents] AS [t4] ON [t3].[AgentVersionKey] = [t4].[VersionKey]
) AS [t5]
WHERE ([t5].[IsCurrentVersion2] = 1) AND ([t5].[Status] = @p0) AND ([t5].[IsCurrentVersion] = 1) AND ([t5].[IsActive] = 1)',N'@p0 int',@p0=7
显示名称方法
public string DisplayName
{
get
{
if (!string.IsNullOrEmpty(this.RxNormTallMan))
{
return this.RxNormTallMan;
}
else if (!string.IsNullOrEmpty(this.NccnTallMan))
{
return this.NccnTallMan;
}
return this.Name;
}
}
【问题讨论】:
-
这是一个包含子查询的选择语句,但它仍然是一个语句。编写 LINQ 语句(不一定会导致不同的 SQL 查询)的更好方法是删除所有
join语句并使用导航属性。您的存储库层似乎更像是一个障碍而不是帮助。我猜最终选择包含所有字段,因为DisplayName不是映射字段,并且 L2S 切换到客户端评估。我们只能在看到类模型时才知道。 -
我包含了 Model 类
-
在我正在做的控制器中
return Json(agents.ToList().OrderBy(a => a.Name)); -
那不是类模型。 L2S 创建一个类模型(带有导航属性 BTW!)。显示生成的代码可能太多了。主要问题是,
DisplayName是映射属性吗? -
是的,我没有发现 L2S 如何创建该类有任何问题
标签: c# linq-to-sql unit-of-work