【问题标题】:Linq to SQL Query Returning DataLinq to SQL 查询返回数据
【发布时间】: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 =&gt; a.Name));
  • 那不是类模型。 L2S 创建一个类模型(带有导航属性 BTW!)。显示生成的代码可能太多了。主要问题是,DisplayName 是映射属性吗?
  • 是的,我没有发现 L2S 如何创建该类有任何问题

标签: c# linq-to-sql unit-of-work


【解决方案1】:

这里的关键是DisplayName 不是一个映射 属性。 IE。 is 与数据库字段不对应。因此,该属性没有 SQL 翻译。 LINQ-to-SQL 检测到这一点并决定它所能做的最好的事情是获取所有表的所有字段并在客户端(即内存中)构建所需的投影 (AgentDto)。

如果您希望 L2S 仅选择必填字段,则必须在 select 语句中仅使用映射属性:

select new Data.Dto.Agent.AgentDto
{
    Name = a.RxNormTallMan.Length > 0 
        ? a.RxNormTallMan 
        : a.NccnTallMan.Length > 0
            ? a.NccnTallMan
            : a.Name,
    VersionKey= a.VersionKey 
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    相关资源
    最近更新 更多