微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用Entity Framework 6从两个多对多表中获取不会导致UNION ALL的数据?

如何解决如何使用Entity Framework 6从两个多对多表中获取不会导致UNION ALL的数据?

我想使用Entity Framework一个根表中从两个 多对多关系表中获取数据,但是当我这样做时,结果查询UNION ALL产生。我想避免这种情况,因为它会扫描根表两次,从而导致性能下降。 是否可以用EF6来执行此操作而不必编写显式的联接,子查询,存储过程?

您说什么是性能最佳的解决方案,什么是可维护性/可读性的最佳解决方案?

请注意,我需要返回IQueryable方法,以便可以应用OData查询选项,并希望在一次查询获取所有数据,然后将其转换为JSON。 / p>

也许我错过了一个简单的解决方案,任何帮助将不胜感激!

这些是我的实体:

//My main table
public class Root 
{
    public int Id { get; set; }

    public virtual ICollection<RootStock> RootStocks { get; set; }

    public virtual ICollection<RootSector> RootSectors { get; set; }
}

//My junction table #1
public class RootStock
{
    [Key,Column(Order = 0)]
    public int RootId { get; set; }

    [Key,Column(Order = 1)]
    public int StockId { get; set; }

    [ForeignKey("RootId")]
    public virtual Root Root { get; set; }

    [ForeignKey("StockId")]
    public virtual Stock Stock { get; set; }
}

//My junction table #2
public class RootSector 
{
    [Key,Column(Order = 0)
    public int RootId { get; set; }

    [Key,Column(Order = 1)
    public int SectorId { get; set; }

    [ForeignKey("RootId")]
    public virtual Root Root { get; set; }

    [ForeignKey("SectorId")]
    public virtual Stock Stock { get; set; }
}

//My target table #1
public class Stock
{
    public int Id { get; set; }

    public string Name { get; set; }

    public virtual ICollection<RootStock> RootStocks { get; set; }
}

//My target table #2
public class Sector
{
    public int Id { get; set; }

    public string Name { get; set; }

    public virtual ICollection<RootSector> RootSectors { get; set; } 
}

使用UNION ALL进行查询方法

public IQueryable<RootResponse> GetAll()
{
     var result = from root in _rootProvider.GetAllQuery()
             select new RootResponse
             {
                  Id = root.Id,StockNames = root.RootStocks.Select(x => x.Stock.Name).AsQueryable(),SectorNames = root.RootSectors.Select(x => x.Sector.Name).AsQueryable()
             };

     return result;
}

GetAllQuery()中没什么特别的>

public IQueryable<Root> GetAllQuery()
{
    return _dbContext.Roots.AsNoTracking();
}

这是生成查询

SELECT 
    [UnionAll1].[Id] AS [C1],[UnionAll1].[Id1] AS [C2],[UnionAll1].[C1] AS [C3],[UnionAll1].[Name] AS [C4],[UnionAll1].[C2] AS [C5]
    FROM  (SELECT 
        CASE WHEN ([Join1].[RootId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1],[Extent1].[Id] AS [Id],[Extent1].[Id] AS [Id1],[Join1].[Name] AS [Name],CAST(NULL AS varchar(1)) AS [C2]
        FROM  [dbo].[Roots] AS [Extent1]
        LEFT OUTER JOIN  (SELECT [Extent2].[RootId] AS [RootId],[Extent3].[Name] AS [Name]
            FROM  [dbo].[RootStocks] AS [Extent2]
            INNER JOIN [dbo].[Stocks] AS [Extent3] ON [Extent2].[StockId] = [Extent3].[Id] ) AS [Join1] ON [Extent1].[Id] = [Join1].[RootId]
    UNION ALL
        SELECT 
        2 AS [C1],[Extent4].[Id] AS [Id],[Extent4].[Id] AS [Id1],CAST(NULL AS varchar(1)) AS [C2],[Join3].[Name] AS [Name]
        FROM  [dbo].[Roots] AS [Extent4]
        INNER JOIN  (SELECT [Extent5].[RootId] AS [RootId],[Extent6].[Name] AS [Name]
            FROM  [dbo].[RootSectors] AS [Extent5]
            INNER JOIN [dbo].[Sectors] AS [Extent6] ON [Extent5].[SectorId] = [Extent6].[Id] ) AS [Join3] ON [Extent4].[Id] = [Join3].[RootId]) AS [UnionAll1]
    ORDER BY [UnionAll1].[Id1] ASC,[UnionAll1].[C1] ASC;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。